Skip to content
Stove
Last Updated

Curious about the actual application flow?

Usage Scenarios / Signing In

Authentication (Tokens & Validation)

Understanding


STOVE authentication is the procedure that proves identity so that the game client, game server, and web services can safely use STOVE platform user information. By integrating authentication, you can receive the authentication info of users logged in with a STOVE account—without building your own membership system—and use it for all services that require authentication, such as game entry, API calls, payment, and sanction handling.

Components of Authentication

STOVE authentication operates via two main paths depending on the authenticating party.

Path Authenticating party Platform used Issued token
User authentication Each logged-in user Mobile SDK, PC SDK, Web User Access Token, Refresh Token
Server authentication Game server (system) Server API Access Token

Understanding the two authentication paths
ㅁ User authentication: the SDK/web module handles STOVE login and issues a User Access Token.
ㅁ Server authentication: the game server obtains an API Access Token with client_id/client_secret and uses it for API calls.
ㅁ The two tokens have different roles and can't substitute for each other. When validating a user token, the game server also uses its own API Access Token.

Authentication Flow Paths by Platform

The authentication flow path and the tools used differ by the platform the game launches on (Mobile/PC/Web/Server).
Integrate only the areas you need, matching your game's launch form.

Platform Integration tools Obtained info Main use
Mobile Mobile SDK (Android/iOS/Unity/Unreal) User Access Token, member identifier
(guid or member_no)
Mobile game login and game-server authentication
PC PC SDK (PCSDK3) + STOVE PC Client User Access Token, member identifier
(guid or member_no)
PC game execution authentication and game-server authentication
Web STOVE Web authentication
(GNB method or login URL method)
SUAT
(cookie-based Web Access Token)
Login integration for the game's official homepage and event pages
Server STOVE Platform API
(Server-to-Server)
API Access Token Backend API calls such as user-token validation, sanction lookup,
and member-info lookup

Notes on platform integration
ㅁ Multi-platform games integrate the areas they need together, such as Mobile + PC + Server.
ㅁ If there's any flow where the game server calls the STOVE API, Server authentication is required regardless of platform.

Token Types and Roles

STOVE issues three main kinds of tokens, each with a different role and expiry time.

Token Type How to obtain Role Validity
User access token
(User Access Token)
SDK Issued on successful user login. Used for user authentication and proof of authority.
Short validity for security—valid for only 6 hours.
6 hours
(21600000ms)
Refresh token
(Refresh Token)
Used to reissue when the user access token expires.
Allows renewing the access token without separate authentication for a certain period.
Auto-renewed inside the SDK. Take care not to use this token directly.
720 hours
(30 days)
Platform API access token
(API Access Token)
API Used as the authentication method when calling STOVE-provided APIs.
Long validity; must be reissued after expiry.
720 hours
(30 days)

Token Usage Policy

These are usage principles that all environments must follow in common, regardless of token type.

Principle Description
Do not cache the User Access Token Valid for only 6 hours after issuance. Can change due to the user's re-login, refresh, logout, etc.
Always look it up in real time via the SDK when needed.
Auto-renewal is handled by the SDK The SDK auto-renews with the Refresh Token at 80% of the expiry time.
Do not handle the Refresh Token directly in game code.
Manage the API Access Token only on the server For server-to-server authentication, valid for 30 days. Do not expose it to the client, external systems, or logs.
Store expires_in to renew before expiry, or keep it current by calling periodically 1–2 times a day.
The game server must not persist user tokens The client passes the User Access Token with each request, and the game server calls the validation API with that token.

Game Identifiers Summary

The game-identifier terms used in STOVE authentication and APIs are below.
The standard identifier is Game ID (string).

Term Description Notes
Game ID A unique string that identifies the game.
Stays the same regardless of environment (Sandbox/Live).
The standard identifier officially provided by the sanction API and others.
Game No A numeric code assigned to distinguish games. Not used in current integration. Use Game ID as the identifier.
Service ID An ambiguous term where Game No and Game ID are used interchangeably. Ambiguous, so not used.
  • The member identification number inside the STOVE platform is member_no (numeric).
  • Currently integrated games receive guid as the member identifier.

Authentication Add-on Features

These are add-on features the STOVE authentication system provides in addition to basic authentication.

Feature Supported platforms Description
Email verification Mobile SDK Confirms identity by sending a verification code/link to the account's email. Mobile email-account verification is required from SDK 2.8.0.
STOVE email accounts use the sign-up email; 3rd-party accounts use the secondary email set in 'My Info'.
Web authentication (GNB / login URL) Web Uses STOVE login on websites.
The GNB method (recommended) provides a responsive GNB UI module; the login URL method links directly to the STOVE login page.
Available on the xxx.game.onstove.com domain.
Member sanction-status lookup Server The game server queries the STOVE API for a member's platform-sanction, game-sanction, and posting-sanction status.
Even when multiple sanctions exist, it responds with a single code by priority.

Integration Guide


Platform-specific Prerequisites

Depending on your game's launch form, you only need to do the prerequisites for the platforms you need.

Platform Required items
Mobile ㅁ Download the Mobile SDK and apply it to the project
ㅁ Set App ID / Client ID
ㅁ Register the package/bundle ID for iOS and Android separately
PC ㅁ Download the PC SDK (PCSDK3) and apply it to the project
ㅁ Set App ID / Client ID
ㅁ Verify the game-execution path via the STOVE PC Client (launcher)
Server ㅁ Request the API Access Token issuance keys
ㅁ Provide the Game ID to the publishing technical contact to have client_id, client_secret, and service_id issued
ㅁ Issued separately per service environment (Live, Sandbox)
Web ㅁ Usable only when the integrated web service domain is xxx.game.onstove.com
ㅁ The fourth-level domain connection is applied through the technical PM
ㅁ An SSL certificate must be issued when using external infrastructure
ㅁ Inflow-path codes such as inflow_path are also issued through the technical PM

Environment-separated issuance is required
Always issue keys and tokens separately per environment (Live/Sandbox) and don't mix them.
Mixing environments causes 40105 (client_id/client_secret mismatch) or 41002 (service_id mismatch) errors in the validation API.

Full Authentication Flow

Even across platforms (Mobile/PC/Web), the order in which authentication proceeds is the same. They all follow the 5 steps below, and only the concrete way to implement each step differs by platform.

Step Task Actor Description
1 User login Client (SDK/Web) Performs STOVE login via the SDK/web module. Issues a User Access Token on success.
2 Look up the User Access Token Client Look up the latest token via the SDK API each time you use it. No caching.
3 Pass the token to the server Client → game server Pass the User Access Token to the game server when an API call is needed.
4 Issue/renew the API Access Token Game server ↔ STOVE The game server issues/renews the API Access Token with client_id/client_secret.
5 Validation and branching Game server ↔ STOVE Validates the User Access Token via the STOVE validation API.
Branches into normal entry, re-login prompt, or access block based on the response code.

Call the validation API only from the game server
Calling it directly from the client exposes the API Access Token and creates a security problem.
Perform validation on the game server, and the client only receives the result.

Environment Distinction Guide

STOVE provides two environments, Sandbox and Live, to separate the development stage from the operations stage.
Key issuance, domains, and the validation API are all operated separately per environment, so be careful not to mix them.

Category Use When to use
Sandbox Development/test environment SDK integration verification, checking response codes per scenario, QA.
Not exposed to real users.
Live Commercial service environment Service for real users.
Even after launch, verify new features in Sandbox first, then apply to Live.
  • Issue client_id, client_secret, and service_id separately per environment.
  • If the validation API's game_id differs from the service_id of the API Access Token you hold, a 41002 error occurs. Manage them separately per environment and game.

Development


Mobile

Prerequisites

  • The call to Auth.login (Android) / [SGSAuth login] (iOS) / Auth.Login (Unity/Unreal) must be complete. When not logged in, accessToken returns null.
  • Don't cache the token on the client; re-fetch it from the SDK each time you use it. Since the SDK auto-renews at 80% of the expiry time, the value fetched from the SDK is always the latest.
  • Auto-renewal works only while the app process is running. If the process is terminated in the background, renewal stops, so on returning to the foreground, verify the call result and, if expired, guide the user into the re-login flow.
  • Even when you need to pass the token to the game server, don't store it on the server side; pass it along each time a client call occurs.

Development Flow

  1. The game client looks up the latest AccessToken via a per-platform API such as Auth.accessToken?.token (Kotlin) / [[SGSAuth accessToken] token] (iOS).
  2. If the return value is null, the user is not logged in or has logged out, so guide them into the login flow.
  3. If you need to pass the token to the game server, pass the token received from the SDK at call time as-is. Don't store it on the server side; receive it anew with each request.
  4. The game server validates the token with the STOVE platform's Game User Access Token validation API, then branches into normal entry, re-login prompt, access block, etc. (See the game-server guide for the validation API)

Auto-renewal proceeds in the following sequence:

Troubleshooting

Don't cache the AccessToken
Since the SDK auto-renews at 80% of the expiry time, calling Auth.accessToken each time guarantees the latest value. Reusing a token stored on the client or game server causes authentication errors from a token invalidated after expiry/renewal.

SituationCauseAction
accessToken returns nullNot logged in, or just after logoutCheck Auth.accessToken != null before calling, and if null, guide the user into the login flow.
401 authentication failure on API call (expired token)The token expired without auto-renewal running (e.g., returning after a long background)Re-fetch Auth.accessToken each time you use it to get the latest token. If it's still expired, prompt re-login.
Failure when calling with a token stored on the game serverThe token was invalidated by the client's re-login, logout, or auto-renewalThe game server should not persist the token; use the latest token received with the client request to call the STOVE validation API.
Auto-renewal doesn't runThe app process was terminated in the background, halting the SDK callbackRe-fetch the token on returning to the foreground (onResume / applicationDidBecomeActive), and prompt re-login if expired.

Sample Code

csharp
public void GetToken()
{
    string token = Auth.AccessToken.Token;
}

PC (PCSDK)

Prerequisites

  • BaseSDK initialization (Base_RestartAppIfNecessaryAsyncBase_InitializeEx) and login completion must come first. Calling before initialization returns BASE_NOT_INITIALIZED (16).
  • Pre-allocate a sufficiently large buffer to receive the AccessToken. If the length is insufficient, INVALID_PARAM (5) may be returned.
  • The client_id / client_secret / service_id for API Access Token issuance must be held by the game server and must not be exposed to the client.
  • Don't cache the token; re-fetch it via the SDK when needed. It can be invalidated at any time by the user's re-login, logout, or session change.

Development Flow

  1. The game client calls Base_GetAccessToken(buffer, length) to get the latest User Access Token.
  2. Validate the returned result (Result) with IsSuccessful(). (Both C/C++ and C# use result.IsSuccessful())
  3. If the token needs to be used on the game server, the client passes it to the game server. Don't store it on the server side; receive and pass it again at call time.
  4. The game server calls the STOVE platform's Game User Access Token validation API to perform a secondary validation of the token. This requires the API Access Token in the Authorization header.
  5. Branch the follow-up handling—normal entry, re-login prompt, access block, etc.—based on the validation response code.

Troubleshooting

SituationCauseSolution
Calling Base_GetAccessToken right after game start returns BASE_NOT_INITIALIZED (16)Base_RestartAppIfNecessaryAsync is async, so initialization isn't complete before the callback arrives. Initialization completes only when Base_InitializeEx is called in the callback's restartAppIfNecessary == false branch; fetching the token before that causes error 16.In the Base_RestartAppIfNecessaryAsync callback, confirm restartAppIfNecessary == false, call Base_InitializeEx, and only look up the token after initialization succeeds. Typically, finish initialization before entering the title screen and look up the token after the login step.
A server call after the user has played for a while returns INVALID_ACCESS_TOKEN (19)Base_GetAccessToken returns the latest token on every call, so error 19 doesn't occur in a normal environment. If it does, the cause is a temporary network failure or an abnormal SDK state.If 19 is returned, don't continue the game; show "Please restart via the STOVE PC Client" and then exit the game. Don't cache the token in a member variable; fetch it with Base_GetAccessToken right before each game-server call to avoid issues.
The token string is truncated, or INVALID_PARAM (5) is returnedThe token length is variable and may grow in the future, so a small buffer (e.g., 256/1024 bytes) is insufficient.Allocate and pass a wchar_t buffer of size 4096. Don't process the received token by length; send it to the game server as-is to avoid issues.
FAIL (1) is returnedBase_GetAccessToken is a local cache lookup and involves no communication, so error 1 doesn't occur in a normal environment. If it does, the cause is an abnormal internal SDK state (memory corruption, missing token actor, etc.).As with 19, don't continue the game; show "Please restart via the STOVE PC Client" and then exit the game.

You must not cache the User Access Token
It's valid for only 6 hours after issuance and changes at any time due to the user's re-login or logout. Server-side storage or client caching causes authentication errors from expired/changed tokens. Always get the latest value with Base_GetAccessToken each time you use it.

Manage the API Access Token only on the game server
It's a server-to-server authentication token valid for 30 days, so it must not be exposed to the client. The game server issues it with client_id/client_secret and renews it based on expires_in. If the existing token has 30% or more validity remaining, the same token is issued; if less, a new token is issued.

Sample Code

cpp
// Assumes Base_RunCallback() is registered to be called in the game loop.
constexpr uint32_t kTokenBufferSize = 4096;
wchar_t accessToken[kTokenBufferSize] = { 0 };

auto result = Stove::PCSDK::Base::Base_GetAccessToken(accessToken, kTokenBufferSize);
if (result.IsSuccessful())
{
    // Send the accessToken string to the game server to perform validation.
}
else
{
    // Implement the failure logic (prompt re-login, user guidance, etc.).
}

Server

Prerequisites

  • The game server must hold client_id / client_secret / service_id.
    For the issuance procedure and environment (Live/Sandbox) separation, see 2. Integration Guide → Token Issuance Prerequisites above.
  • The structure must receive the Game User Access Token from the client with each request. Don't cache it on the game server.

Development Flow

  1. The client passes the Game User Access Token to the game server.
  2. The game server checks the remaining validity of the API Access Token it holds. (Based on the expires_in received at issuance)
  3. If there's no token or less than 30% remaining, call POST /auth/v5/server_token to issue/renew the API Access Token.
    If 30% or more remains, the same token is returned, so you can use the response's access_token as-is.
  4. Call POST /member/v3.0/{game_id}/token/verify to validate the Game User Access Token received from the client.
    Put Bearer {API Access Token} in the Authorization header.
  5. Branch based on the response code: normal entry (code == 0), re-login prompt, device-registration prompt, access block, etc.
    Identify the user by the response value.guid (GUID-based games) or value.member_no.

Troubleshooting

These are handling approaches per response code. For the detailed response-code and message spec, see the API & SDK Reference menu.

Response codeSituationHandling approach
40000The Game User Access Token is invalid or expired, or the request body is wrongPrompt the client to re-login, and verify the request body is correct.
40101The API Access Token is invalid (wrong Authorization header value)Reissue the API Access Token and retry.
40103The API Access Token expiredCall POST /auth/v5/server_token to renew it, then retry.
40105client_id / client_secret mismatch when calling the issuance APICheck that you aren't mixing keys across environments (Live/Sandbox).
41002The game_id in the validation API path differs from the service_id of the API Access Token you holdIssue and manage the API Access Token separately per environment and game.
46217(Mobile device-registration games only) A registered member with an unregistered deviceGuide the client into the device-registration flow.
Doesn't occur when validating with a token obtained in the PC SDK environment.
50000Unknown errorIt may be a temporary error, so retry; if it persists, inquire through the technical PM.

The API Access Token must not be exposed outside the game server
Be careful not to print it to the client, external systems, or logs. If exposed, reissue it immediately.

Use instance_id to separate token lifetimes across multiple server instances
If you don't specify instance_id, the same token is issued to all servers based on client_id.
If you want to separate issuance/renewal cycles per instance, pass instance_id with the issuance request.

Sample Code

Examples of calling API Access Token issuance (POST /auth/v5/server_token) and Game User Access Token validation (POST /member/v3.0/{game_id}/token/verify).

Replace the Base URL to match the environment (Live/Sandbox)
In production, instead of hardcoding, we recommend separating it into an environment variable (e.g., STOVE_API_BASE_URL) or a framework config file and injecting it per environment.

java
// Java 25 LTS — java.net.http.HttpClient + Jackson(ObjectMapper)
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;

ObjectMapper mapper = new ObjectMapper();
String baseUrl = "https://api.onstove.com";
String serviceId = "STOVE_GAME";
String callerId = serviceId + "_SERVER";

try (HttpClient client = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(5))
        .build()) {

    // 1) Issue the API Access Token
    String issueBody = mapper.writeValueAsString(Map.of(
            "client_id", "com.stove.stovegame.clientid",
            "client_secret", clientSecret,
            "service_id", serviceId,
            "instance_id", "server001"));

    HttpRequest issueReq = HttpRequest.newBuilder(URI.create(baseUrl + "/auth/v5/server_token"))
            .header("Content-Type", "application/json")
            .header("caller-id", callerId)
            .POST(HttpRequest.BodyPublishers.ofString(issueBody))
            .build();
    HttpResponse<String> issueRes = client.send(issueReq, HttpResponse.BodyHandlers.ofString());
    JsonNode issueData = mapper.readTree(issueRes.body());
    if (issueData.path("code").asInt() != 0) {
        // See the troubleshooting table (40105, etc.)
        throw new IllegalStateException("Token issue failed: " + issueData.path("code"));
    }
    String apiAccessToken = issueData.path("response_data").path("access_token").asText();

    // 2) Validate the Game User Access Token
    String verifyBody = mapper.writeValueAsString(Map.of(
            "access_token", gameUserAccessToken));

    HttpRequest verifyReq = HttpRequest.newBuilder(
            URI.create(baseUrl + "/member/v3.0/" + serviceId + "/token/verify"))
            .header("Content-Type", "application/json")
            .header("Authorization", "Bearer " + apiAccessToken)
            .header("caller-id", callerId)
            .POST(HttpRequest.BodyPublishers.ofString(verifyBody))
            .build();
    HttpResponse<String> verifyRes = client.send(verifyReq, HttpResponse.BodyHandlers.ofString());
    JsonNode verifyData = mapper.readTree(verifyRes.body());
    if (verifyData.path("code").asInt() == 0) {
        JsonNode value = verifyData.path("value");
        // Identify the user by value.path("guid").asLong() or value.path("member_no").asLong()
    } else {
        // See the troubleshooting table (40000 / 40101 / 41002 / 46217, etc.)
    }
}

Frequently Asked Questions



Q1. Can I store the User Access Token on the server and reuse it?
A. You must not cache the User Access Token or store it on the server for reuse.
It's valid for only 6 hours after issuance and can change at any time due to the user's re-login, refresh, logout, etc.
An expired or changed token can cause authentication errors (validation failure), so always look it up in real time via the SDK whenever needed.
Q2. How should I renew the API Access Token?
A. The game server should periodically call the API Access Token issuance API to renew the server access token, or store expires_in and refresh via the issuance API before expiry.
When calling the issuance API, if the existing token has 30% or more validity remaining, the existing token is returned as-is; if less than 30%, a new token is issued.
Previously issued tokens can continue to be used until their validity expires.
Q3. How do I set up authentication for a multi-platform (Mobile + PC + Web) game?
A. Integrate client authentication (Mobile SDK / PC SDK / Web) separately per platform, and place common API Access Token issuance/validation logic on the game server.
The User Access Token is issued differently per platform, but the validation API (/member/v3.0/{game_id}/token/verify) is the same, so the game server can process a token from any environment with the same flow.
The STOVE member identifier (guid or member_no) is also the same regardless of platform, so account continuity is maintained.
Q4. For web authentication, should I choose the GNB method or the login URL method?
A. The GNB method is recommended.
Since it integrates the STOVE GNB UI and features via a JavaScript module, you can build it responsively across PC, tablet, and mobile, and per-service customization is easy.
If you have a web service that isn't using the GNB integration and must link the STOVE login page directly, use the login URL method.
Q5. When the game server queries sanction status and there are multiple sanctions, how are they handled?
A. Even when multiple sanctions exist, it responds with a single code by priority.
If any platform sanction exists, it returns a platform-sanction code (403101–403103) with top priority.
If there's no platform sanction but a game sanction, it returns 403201; if only a posting sanction, it returns 403202. The client can handle user-access blocking and messaging based on the code value.
Q6. In the sanction API, which identifier should I use: game_id, game_no, or service_id?
A. For new API integration and guides, you must use the Game ID (string).
Game No (numeric code) was used in legacy systems and is not used in current integration.
The term "Service ID" causes ambiguity, so we recommend not using it in guides or code.



Need to contact us directly? stove.developers@smilegate.com