A simple REST API used to keep track of high scores, made in ASP.NET Core 6.0
docker-compose up --build
By default the API starts on 127.0.0.1:5205
.
You can change this in docker-compose.yml
.
All endpoints require authentication using the X-API-Key
header.
Make sure to change the default allowed client and admin keys in appsettings.json
.
Method | Endpoint | Description | X-API-Key |
---|---|---|---|
GET | /{projectName}/top/{amount} |
Get the top amount of highest scores |
Client |
GET | /{projectName}/search/{username} |
Get the high score of user by username |
Client |
POST | /{projectName} |
Add a new high score (Encrypted body) | Client |
DELETE | /{projectName} |
Delete a high score | Admin |
Method | Endpoint | Description | X-API-Key |
---|---|---|---|
GET | /search/{projectName} |
Get a project by projectName |
Admin |
POST | / |
Add a new project | Admin |
DELETE | /{projectName} |
Delete a project with all high scores by projectName |
Admin |
Method | Endpoint | Description | X-API-Key |
---|---|---|---|
GET | /{projectName}/random |
Get a random username that has not set a high score | Client |
By default, the API requests you to send encrypted high scores.
If you want to disable this behaviour, remove this line in Program.cs
:
app.UseMiddleware<EncryptionMiddleware>();
The first step is to create a new project. Send a POST request to /api/projects
.
The name
must be between 1
and 64
characters. Whitespaces will be replaced by dashes.
Example JSON
:
{
"name": "My-Game"
}
The API will respond with an encryption key. You can use this key to encrypt a high score.
Example JSON
:
{
"name": "My-Game",
"aesKeyBase64": "HbrBX/TckMpgKFKZbLQsJkkfE3bUKJ1JuD2CPZbxt48="
}
In AesOperation.cs, you can see how to encrypt the high score.
Use this implementation on the client to encrypt the high score.
public static string EncryptData(string plainText, string keyBase64, out string vectorBase64)
{
using Aes aes = Aes.Create();
aes.Key = Convert.FromBase64String(keyBase64);
aes.GenerateIV();
vectorBase64 = Convert.ToBase64String(aes.IV);
ICryptoTransform encryptor = aes.CreateEncryptor();
using MemoryStream ms = new();
using CryptoStream cs = new(ms, encryptor, CryptoStreamMode.Write);
using StreamWriter sw = new(cs, Encoding.ASCII);
sw.Write(plainText);
sw.Close();
byte[] encryptedData = ms.ToArray();
return Convert.ToBase64String(encryptedData);
}
// Generated key associated with project
const string AesKeyBase64 = "HbrBX/TckMpgKFKZbLQsJkkfE3bUKJ1JuD2CPZbxt48=";
// The username must be between 1 and 64 characters. Detected profanity will be removed from the name.
// The score must be 1 or higher.
var highScore = new HighScore() { Username = "user", Score = 10 };
string jsonString = JsonConvert.SerializeObject(highScore);
// Encrypt the JSON string to receive cipherText and vectorBase64
string cipherText = EncryptData(jsonString, AesKeyBase64, out string vectorBase64);
Now that you have an encrypted high score and a vectorBase64
, you can POST the cipherText
to /api/highscores/{projectName}
.
Use the header Content-Type
with the value application/json
, since the high score will be JSON after it's been decrypted.
Add an extra header called AES-Vector
with the value of vectorBase64
.
The API uses this to decrypt the body of the request.
That's it, your high score should now be added to the database!
Try fetching /api/highscores/{projectName}/top/10
to see it in the list.