Steps to Update the Langman API
Learn the steps for updating the Langman API.
We'll cover the following
Run server
First, we need to run it just as we did before, except that we need to
specify the JWT_SECRET_KEY
environment variable.
$ export FLASK_APP=server.app
$ export FLASK_ENV=dev_lite
$ export FLASK_JWT_SECRET_KEY=9876543210blastoff
$ pipenv run flask run --host=0.0.0.0 --port=3000
This terminal will now wait and report on communications to port 3000
.
The POST
method
We need to open a new terminal to play the game. We show the full access token only the first time to show how long it is, but then abbreviate it using …
in the other cases.
$ http POST 0.0.0.0:3000/api/auth username=Bobby password=s3cr3t
HTTP/1.0 200 OK
...
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Nzk4Mzc2MzcsIm5iZiI6MTU3OTgzNzYzNywianRpIjoiOTQyNTNmZDAtODFjOS00NDMzLWIxYzYtZDg2MTgxZDUyMzQ1IiwiZXhwIjoxNTc5OTI0MDM3LCJpZGVudGl0eSI6Ijc3MWJhM2YwLWI4YmYtMzJkYy04ODhkLTQ3N2E5ODkzNGM5ZCIsImZyZXNoIjpmYWxzZSwidHlwZSI6ImFjY2VzcyIsInVzZXJfY2xhaW1zIjp7ImFjY2VzcyI6InBsYXllciIsIm5hbWUiOiJCb2JieSJ9fQ.l0OEB-liBD1zNazBxhj_ZMMEpnqRNjdQoY6MlPItrhM"
}
$ export JWT=eyJ0eXAiOiJKV1...pnqRNjdQoY6MlPItrhM
With the token stored as an environment variable, it becomes easier to start a game.
$ http POST 0.0.0.0:3000/api/games language="en" "Authorization:Bearer $JWT"
HTTP/1.0 200 OK
...
{
"access_token": "eyJ0eXAiOiJKV1Qi...6wH6LM6XmDKzBpBWrDI",
"game_id": "1ad1e8ca-91da-47d4-8dad-7a72cad0094b",
"message": "success"
}
$ export JWT2=eyJ0eXAiOiJKV1Qi...6wH6LM6XmDKzBpBWrDI
$ export GAME=1ad1e8ca-91da-47d4-8dad-7a72cad0094b
The GET
method
We can get the information of the game using the game ID
$ http GET 0.0.0.0:3000/api/games/$GAME "Authorization:Bearer $JWT"
HTTP/1.0 200 OK
...
{
"access_token": "eyJ0eXAiOiJKV1Qi...WEueRXwIeTJS7r87eEw",
"bad_guesses": 0,
"end_time": null,
"game_id": "1ad1e8ca-91da-47d4-8dad-7a72cad0094b",
"guessed": "",
"lang": "en",
"player": "771ba3f0-b8bf-32dc-888d-477a98934c9d",
"result": "active",
"reveal_word": "_______",
"source": "Pride and Prejudice by Jane Austen",
"start_time": 737447,
"usage": "Mrs. Bennet, accompanied by her two youngest girls, _______
Netherfield soon after the family breakfast. ",
"usage_id": 1916
}
The PUT
method
Playing the game is done by guessing letters. This requires both the game ID and the game-specific access token granting access to play that game. After the first response, we leave out most of the response for brevity.
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=e Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 0,
"end_time": null,
"game_id": "1ad1e8ca-91da-47d4-8dad-7a72cad0094b",
"guessed": "e",
"lang": "en",
"player": "771ba3f0-b8bf-32dc-888d-477a98934c9d",
"result": "active",
"reveal_word": "_e___e_",
"source": "Pride and Prejudice by Jane Austen",
"start_time": 737447,
"usage": "Mrs. Bennet, accompanied by her two youngest girls, _______
Netherfield soon after the family breakfast. ",
"usage_id": 1916
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=a Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 0,
"guessed": "ea",
"result": "active",
"reveal_word": "_ea__e_",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=d Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 0,
"guessed": "ead",
"result": "active",
"reveal_word": "_ea__ed",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=t Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 1,
"guessed": "eadt",
"result": "active",
"reveal_word": "_ea__ed",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=s Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 2,
"guessed": "eadts",
"result": "active",
"reveal_word": "_ea__ed",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=r Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 2,
"guessed": "eadtsr",
"result": "active",
"reveal_word": "rea__ed",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=c Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 2,
"guessed": "eadtsrc",
"result": "active",
"reveal_word": "reac_ed",
}
$ http PUT 0.0.0.0:3000/api/games/$GAME letter=h Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"bad_guesses": 2,
"guessed": "eadtsrch",
"result": "won",
"reveal_word": "reached",
"secret_word": "reached",
}
In the end, it provides the secret word and changes the result from “active” to “won”. We can see that quotes are placed around Bearer
, sometimes before Authorization
and sometimes after it. This is to let httpie know that the token is part of the header value. Otherwise, it interprets the space between Bearer
and the token as indicating the end of the header value.
The DELETE
method
There is always the option to delete the game and even the user. The first command deletes the game, while the second one deletes the user.
$ http DELETE 0.0.0.0:3000/api/games/$GAME Authorization:"Bearer $JWT2"
HTTP/1.0 200 OK
...
{
"message": "One record deleted"
}
$ http DELETE 0.0.0.0:3000/api/auth Authorization:"Bearer $JWT"
HTTP/1.0 200 OK
...
{
"deleted_user_id": "771ba3f0-b8bf-32dc-888d-477a98934c9d"
}
Finally, note that all of this security mainly helps with data integrity. Its success in providing access restrictions depends on also having data confidentiality, which is achieved by using HTTPS instead of HTTP. Without HTTPS, the tokens are sent unprotected, and anyone who sees the packets passing between the client and the server can view,and steal, the token. Ensuring that HTTPS is used is a deployment requirement that will be handled automatically by Heroku.
Get hands-on with 1400+ tech skills courses.