While some API methods are open to anonymous public access, others require authentication. When required, requests should include include their access token via the Authorization header using the Bearer schema. Tokens are encoded as JWTs.
An access token (and the two other tokens that are involved in session management) are acquired by the user via one of the supported login workflows. The access token is short-lived, but can be renewed using a refresh token. An id token is used to access AWS resources.
In addition to the session token triplet, other special-use JWTs may be issued to support workflows like user registration.
A full, authenticated user session consists of three JWTs (identified by the following token_use values):
id – the user's identity (which is generated by AWS Cognito); it contains credentials which are required for direct access to AWS resources (e.g., S3)access – the token used to authenticate API requests for this user; it expires in 60 minutes (at the time of writing); its payload contains useful user informationrefresh – the token used to request a new access token once the previous one expires; refresh tokens expire every 30 days (at the time of writing), with the expectation that they may be revoked early if the user suspects their account has been compromisedThis is an example access token (with linebreaks added):
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjQyZTRjZDhlLWQ2ZjQtNGM3My1iODcyLThk NWE4NjMwMzg5MSJ9.eyJpc3MiOiJodHRwOi8vbG9jYWwucG9ydGFsLnRoZWVuZGxlc3NtaXNzaW9uLmN vbS9hdXRoL3N0ZWFtIiwiYXVkIjoiaHR0cDovL2xvY2FsLnBvcnRhbC50aGVlbmRsZXNzbWlzc2lvbi5 jb20vYXV0aC9zdGVhbSIsImNsaWVudF9pZCI6Imh0dHA6Ly9sb2NhbC5wb3J0YWwudGhlZW5kbGVzc21 pc3Npb24uY29tL2F1dGgvc3RlYW0iLCJqdGkiOiI1YTQyN2QxZS0xNDA3LTQ2YjgtYWU0MC0wYTJkMzl hMmE2NzMiLCJzdWIiOiJjZTQ0NGFhMC03ODEzLTQ3OTAtYWVhZi1jOTc0YzdiOGRjMWUiLCJ1c2VybmF tZSI6InRjb2xlc2RldiIsInRva2VuX3VzZSI6ImFjY2VzcyIsImlhdCI6MTU1MDg2MDY1MiwiZXhwIjo xNTUwODY0MjUyfQ.Mok90rfOVe9VIOGCSsk6tDUkJpbyq-FTuzt_zIy8g-CRGpMHoQNPG5qkJREtAX_j hNjaGxtTP486WtpK99-mImbAL0AlMYX_3tMoL2nYS0_dk9ta9rkFekmRdJAO3bHJjIgNH5eRsUY4rPdc X2MKEFNjoZfIqVjOpMuihWuD1NI5nXf65BhnuGyt7VkFmcWuBXLB_8ou0WFr-Dg6-iEuZyax8UoxjKqF Y3z9QSWTw0LqGydMfzx_SgBgn3PfkH3BL9z2y96KmnT_SP5Y29NCyJIxO_KklW_afeWJT35MXEs7Llni 7sTDzoDV4qA7cD01dqib8E9-xnNu-jpuQ3scJw
Its header and payload are decoded into the following objects:
{
"alg": "RS256",
"typ": "JWT",
"kid": "42e4cd8e-d6f4-4c73-b872-8d5a86303891"
}{
"iss": "http://local.portal.theendlessmission.com/auth/steam",
"aud": "http://local.portal.theendlessmission.com/auth/steam",
"client_id": "http://local.portal.theendlessmission.com/auth/steam",
"jti": "5a427d1e-1407-46b8-ae40-0a2d39a2a673",
"sub": "ce444aa0-7813-4790-aeaf-c974c7b8dc1e",
"username": "tcolesdev",
"token_use": "access",
"iat": 1550860652,
"exp": 1550864252
}iss (issuer) tells you who issued the token, client_id tells you who asked for the token, and aud (audience) tells you who the token is intended for. In this case, all three are the same. jti is a unique identifier for this token.
sub (subject) is the user's Content Portal ID, username is their username.
iat (issued at) is when the token was created, and exp (expiration) is when it will expire. (Both are Unix timestamps in seconds.) token_use identifies the role of this token, in this case: an access token, of course.
JWTs were chosen because they can be verified by a server without a round-trip to a central data store, which should reduce load on that data store and speed up request handling. This is especially advantageous because The Endless Mission functionality is expected to be broadly distributed—API servers, external forum websites, multiplayer servers, etc.
Choosing a short-lived access token and a long-lived session token (and the choice of expiration times for each) is a trade-off between security, system performance, and user convenience. If an access token is stolen, the thief gains full access to the user's account. Shortening the lifespan of access tokens minimizes the potential damage, and narrows the window during which a token is vulnerable—i.e., an old token can't be pulled off a hard drive and used months later.
However, it would be unreasonable to ask users to re-authenticate every hour. The refresh token is a mechanism to allow long-lived sessions. Since session tokens are not transmitted with normal requests, they are somewhat less vulnerable than access tokens. Every time a refresh token is used to request a new access token, it is checked against a revoked token list in a central data store. Since this only needs to happen once per hour per active user or so, the load is reasonable.
A sign-up token is issued during the account registration workflow. (This protects users against the possibility that their account could be hijacked in the middle of the registration process.) Sign-up tokens are identified with token_use signup. Its expiration is set to 10 minutes (at the time of writing).