14Plumes / Hexode

MIT License
0 stars 2 forks source link

Game authorization and authentication #13

Open Soreine opened 8 years ago

Soreine commented 8 years ago

We were thinking about using game tokens and user tokens:

Actions Requires Solution
Join a public game as User User authC userToken[userId]
Join a private game as User User authC + authZ userToken[userId] + password
Play a game as User User authC + User is in game gameToken[userId, gameId]
Read a public game - -
Read a private game authZ password OR gameToken[gameId]

We can see that there are 2 types of gameToken. One gameToken for reading a game. The other gameToken for writing (playing) to a game as a certain User.

We should differentiate between a playerToken and a spectatorToken. The spectating mode and spectatorToken can be implemented later. It's important keep the name playerToken because it is unique for each player+game combination.

A playerToken thus contains the gameId and a userId, it acts both as an authentication token and an authorization token. A spectatorToken would contain only the gameId.

Endpoint Requires Returns
Join a game as User userToken + (password) playerToken
Play a game as User playerToken Game + Board updated
Read a private game (password OR playerToken OR spectatorToken) Game + Board
Get a spectatorToken password spectatorToken
KtorZ commented 8 years ago

What about having only one token, the one which give a user the access to request restricted endpoints. If I may reformulate your first table like this:

Actions Requires
Join a public game as User Authenticated User
Join a private game as User Authenticated User + Game Password
Play a game as User Authenticated User + User is in Game
Read a public game -
Read a private game Authenticated User + Game Password

The Authenticated User traduces a session, and we thus have to handle it with a token so that the session management is under the client responsibility.

The Game Password is part of the Game object, and could just be transmitted as a request parameter. No need for a token here.

The "User is in Game" assertion is also part of the Game object. That object is persisted in the database, and is changed on a join request. There is no notion of session here because that action isn't related to the client and it cannot expires. Once a player has joined, the Game object behave differently and accordingly forever; there's no way back. That's why we don't need a token.

However, having no token for a game means to check in the database each time a player is making a move. A game token is a shortcut to prevent the server from reaching the db on every request. For spectator, as we'll only need to check in the db for the join, we can simply stick with the game password.

Thus, we can rather end up with something like this:

Endpoint Requires Returns
Join a public game as User userToken playerToken
Join a private game as User userToken + game password playerToken
Play a game as User playerToken Game + Board updated
Read a public game - Game + Board
Read a private game game password Game + Board
Soreine commented 8 years ago

Any action that needs to access the game will have to read it from the DB at least once, and can be implemented with only 1 access used from the authorization to resolving a move. So let's get rid of any token but the userToken.