OAuth 2.0 / OpenID Connect Integration
Gaijin SSO implements OAuth 2.0 Authorization Code Flow with
OpenID Connect 1.0 .
%%{init: {'theme': 'default', 'flowchart': {'curve': 'basis', 'nodeSpacing': 100}}}%%
sequenceDiagram
participant User
participant Client
participant AuthServer
User->>Client: Open login page
rect rgb(191, 223, 255)
Client->>AuthServer: GET /proxy/oauth/authorize
end
AuthServer->>User: Request login & consent
User->>AuthServer: Enter credentials & consent
AuthServer->>Client: Redirect with authorization code
rect rgb(191, 223, 255)
Client->>AuthServer: POST /proxy/oauth/token (authorization_code)
end
AuthServer->>Client: access_token + id_token (+refresh_token)
rect rgb(191, 223, 255)
Client->>AuthServer: GET /proxy/oauth/userinfo (Bearer access_token)
end
AuthServer->>Client: user profile (email, nickname, etc.)
alt Refresh token
rect rgb(191, 223, 255)
Client->>AuthServer: POST /proxy/oauth/token (refresh_token)
end
AuthServer->>Client: new access_token + id_token (+refresh_token)
end
alt Revoke refresh token
rect rgb(191, 223, 255)
Client->>AuthServer: POST /proxy/oauth/token/revoke
end
AuthServer->>Client: {"status":"ok"}
end
alt JWT → OAuth ID token
rect rgb(191, 223, 255)
Client->>AuthServer: POST /proxy/oauth/exchange (Bearer JWT)
end
AuthServer->>Client: id_token + expires_in
end
alt OAuth access token → User JWT
rect rgb(191, 223, 255)
Client->>AuthServer: POST /proxy/oauth/exchangeToken (Bearer access_token)
end
AuthServer->>Client: user JWT
end
OIDC Configuration
GET /.well-known/openid-configuration
Returns the OpenID Connect configuration for the SSO server.
Authorization
Initiates the Authorization Code flow.
Request
Redirect the user to the authorization endpoint with the following parameters.
GET /proxy/oauth/authorize
response_type string required
Must be code .
response_mode string required
Must be query .
client_id string required
Client identifier, issued together with
client_secret .
redirect_uri string required
Full redirect URI. Hostname must match configuration for the given
client_id .
scope string required
Space-separated list of scopes:
openid
Standard OpenID Connect scope required for authentication and obtaining an
ID token .
offline_access
Allows the client to receive a refresh token and access resources
without requiring the user to re-authenticate.
email
Adds the user’s email address to the
id_token .
profile
Adds the user’s nickname to the
id_token .
trust
Adds email_verified and phone_verified fields to the
UserInfo response.
state string optional (recommended)
Random string to bind ID token to authentication session.
Used for CSRF protection.
The value is generated by the client application and included in the
authentication request. After successful authorization, the same value will be
returned in the redirect_uri as a query
parameter. The client application must verify that the returned
state matches the originally sent value to
ensure that the response corresponds to the authentication request initiated
by the application.
nonce string required
Random string used to associate the authentication request with the returned
ID token and mitigate replay attacks. The value is included in the
authentication request and later verified in the returned ID token.
Request example
GET /proxy/oauth/authorize
?response_type=code
&response_mode=query
&client_id=demo-client
&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback
&scope=openid%20offline_access%20email%20profile
&state=af0ifjsldkj
&nonce=n-0S6_WzA2Mj
Token (Authorization Code / Refresh Token)
Exchanges an authorization code for tokens or refreshes tokens using a
refresh token .
Request
Authorization Code
POST /proxy/oauth/token
Exchanges the authorization code obtained from the authorization step
for an access token and ID token .
Headers:
Authorization string required
Bearer <token> , where token is the SHA1 hash of:
redirect_uri + client_secret
Content-Type string required
Supported values:
Body parameters:
grant_type string required
Must be authorization_code .
code string required
Authorization code received during the authorization step.
redirect_uri string required
Redirect URI used during authorization. Must match the URI used in the
previous step.
Request example
{
"grant_type" : "authorization_code" ,
"code" : "SplxlOBeZQQYbYS6WxSbIA" ,
"redirect_uri" : "https://client.example.com/callback"
}
Refresh Token
POST /proxy/oauth/token
Requests new tokens using a refresh token.
Headers:
Authorization string required
Bearer <token> , where token is the SHA1 hash of:
redirect_uri + client_secret
Content-Type string required
Supported values:
Body parameters:
grant_type string required
Must be refresh_token .
refresh_token string required
Refresh token previously issued by the authorization server.
redirect_uri string required
Redirect URI associated with the client.
Request example
{
"grant_type" : "refresh_token" ,
"refresh_token" : "eyJhbGciOiJSUzI1NiIs..." ,
"redirect_uri" : "https://client.example.com/callback"
}
Response
Success
access_token string required
Token used to access protected resources.
id_token string required
JSON Web Token (JWT) containing identity information about the user.
token_type string required
Always Bearer .
expires_in integer required
Lifetime of the access token in seconds.
refresh_token string optional
Issued only if the requested scopes include offline_access .
Refresh tokens are rotated — only the most recently issued token
remains valid.
Response example
{
"access_token" : "eyJhbGciOiJSUzI1NiIs..." ,
"id_token" : "eyJhbGciOiJSUzI1NiIs..." ,
"token_type" : "Bearer" ,
"expires_in" : 3600 ,
"refresh_token" : "eyJhbGciOiJSUzI1NiIs..."
}
Error
Response example
{
"error" : "invalid_grant" ,
"error_description" : "Authorization code is invalid or expired"
}
ID Token Payload
Structure of the id_token JWT payload.
{
"typ" : "id_token" ,
"aud" : [
"https://login.gaijin.net" ,
"client_id"
],
"azp" : "client_id" ,
"iss" : "https://login.gaijin.net" ,
"exp" : 1664805016 ,
"iat" : 1664804416 ,
"kid" : "381476" ,
"sub" : "11644295" ,
"email" : "user@example.com" ,
"nickname" : "player" ,
"nonce" : "random_string"
}
Additional fields:
Refresh Token Payload
Structure of the refresh_token JWT
payload.
{
"typ" : "refresh_token" ,
"aud" : [
"https://login.gaijin.net" ,
"client_id"
],
"azp" : "client_id" ,
"iss" : "https://login.gaijin.net" ,
"exp" : 1664805016 ,
"iat" : 1664804416 ,
"kid" : "381476" ,
"sub" : "11644295" ,
"scopes" : "openid offline_access"
}
Token lifetime
Token
Lifetime
OAuth session
10 minutes
ID token
1 hour
Access token
1 hour
Refresh token
30 days
JWT Signature Validation (Required)
It is important to verify the JWT signature because:
tokens travel over public networks
signing keys may be rotated or revoked
compromised application keys must be invalidated safely
Public signing keys can be obtained from:
GET /proxy/oauth/keys
Example:
https://login.gaijin.net/proxy/oauth/keys
The response is provided in JWKS format.
Recommended validation flow:
Receive a JWT from the user.
Check that the iss (issuer) is trusted (equals https://login.gaijin.net ).
Check whether the kid exists in the local key cache.
If found, verify the signature.
If not found, request the key set from the JWKS endpoint.
Cache the key and verify the token.
If verification fails, the user should re-authenticate.
UserInfo
Returns user profile information associated with the provided access token.
Tip
This endpoint is compatible with the OpenID Connect UserInfo specification.
Request
GET /proxy/oauth/userinfo
Retrieves information about the authenticated user.
Headers:
Authorization string required
Bearer <access_token> , where
access_token is the access token
obtained from the token endpoint.
Request example
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Response
Success
status string required
sub string required
Unique identifier of the user.
email string optional
User email address. Returned only if email was included in
scope .
email_verified boolean optional
Indicates whether the user’s email address has been verified. Returned only
if trust was included in scope .
nickname string optional
User nickname. Returned only if profile was included in
scope .
phone_verified boolean optional
Indicates whether the user’s phone number has been verified. Returned only
if trust was included in scope .
Response example
{
"status" : "ok" ,
"sub" : "11644295" ,
"email" : "user@example.com" ,
"email_verified" : true ,
"nickname" : "player123" ,
"phone_verified" : false
}
Error
Response example
{
"error" : "invalid_token" ,
"error_description" : "Access token is invalid or expired"
}
Revoke Refresh Token
Revokes a refresh token. This may be required if the token is compromised or the
user session must be terminated.
Tip
This endpoint is conceptually similar to OAuth Token Revocation (RFC 7009).
Request
POST /proxy/oauth/token/revoke
Revokes a previously issued refresh token.
Content-Type:
Supported formats:
Body parameters:
client_id string required
Client identifier issued during application registration.
client_secret string required
Secret associated with the specified
client_id .
refresh_token string required
Refresh token that should be revoked.
Request example
{
"client_id" : "demo-client" ,
"client_secret" : "secret-value" ,
"refresh_token" : "eyJhbGciOiJSUzI1NiIs..."
}
JWT to OAuth ID Token Exchange
Exchanges an existing user JWT for an OAuth-compatible ID token that can be used
with OAuth-protected services.
Request
POST /proxy/oauth/exchange
Exchanges a regular user JWT for an OAuth
id_token .
Headers:
Authorization string required
Bearer <jwt> , where jwt is the user JWT that should be exchanged for an
OAuth ID token.
Request example
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Response
Success
id_token string required
OAuth ID token issued for the provided user JWT.
expires_in integer required
Lifetime of the issued ID token in seconds.
Response example
{
"expires_in" : 600 ,
"id_token" : "eyJhbGciOiJSUzI1NiIs..."
}
Error
Response example
{
"error" : "invalid_token" ,
"error_description" : "Provided JWT is invalid or expired"
}
Access Token to User JWT Exchange
Exchanges an OAuth access token for a user JWT.
Request
POST /proxy/oauth/exchangeToken
Exchanges an OAuth access_token for a
user JWT.
The resulting JWT will include additional claims:
auth = openid
typ = exchanged_token
Headers:
Authorization string required
Bearer <access_token> , where
access_token is the access token
obtained from the OAuth token endpoint.
Request example
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...