Authentication -------------- Stalcraft API uses OAuth 2.0 access tokens to access resources. If you’re not already familiar with the specification, reading this document will help you to better understand how to get access tokens and use them with the Stalcraft API. It is important to treat user's access token, refresh token and application secret like password. You need to protect them and store safely. When making requests which require authorization you should include your token in headers: ``Authorization: Bearer $token``. User Auth Method ~~~~~~~~~~~~~~~~ In OAuth terms this flow is called authorization code grant. APIs that require the user's permission to access information expect user access tokens. This includes all endpoints which return game data that is usually not available to other players. For example, you won't be able to view list of player's characters without user access token. Getting User OAuth Token ========================= To use this method, your app must be able to securely store a client token and make server-to-server requests to the Stalcraft API. To obtain a user access token, your app must first receive authorization from the user and then use the provided authorization code to request the token Get the user to authorize your app ================================== The first step is to get the user to authorize your application's access to their resources. To get the authorization, you should navigate the user to ``https://exbo.net/oauth/authorize``. For example, if you're making a website, you can add the following link for the user to click. ``Login with EXBO Account`` In the link you should specify following query parameters: .. list-table:: :header-rows: 1 :class: tight-table :widths: 1 1 1 10 * - Parameter - Required - Example - Description * - ``client_id`` - Yes - ``30`` - Unique identifier for your application. You will receive it once your application has been :doc:`approved ` * - ``redirect_uri`` - Yes - ``https://yourwebsite.com/code`` - Your app’s registered redirect URI. User will redirected to that page after successful authentication. This URI must match one the values provided during :doc:`registration `. * - ``scope`` - Yes - ```` - Scope required by your application. This parameter is designed for future use. You must specify this parameter, but leave it empty for now. * - ``response_type`` - Yes - ``code`` - Must be set to ``code`` * - ``state`` - No - ``635bc9bc-2915-41d9-9b7b-16f2e86757af`` - This is optional, but strongly encouraged to be used to prevent CSRF attacks. The server will return this string to you when user is sent to redirect URI (look for ``state`` query parameter). If this string doesn't match the state string you passed, ignore the request. The state string is recommended to be randomly generated and unique for each OAuth request. The following url is an example link that you'll will have to navigate user to: .. code-block:: https://exbo.net/oauth/authorize ?client_id=30 &redirect_uri=https://yourwebsite.com/code &scope= &response_type=code &state=635bc9bc-2915-41d9-9b7b-16f2e86757af If the user is already logged into EXBO account, we'll ask them to authorize your application. If they're not logged in, we'll first ask them to log in and then ask them to authorize your application. If the user authorized your application, the server will redirect her using your redirect URI, with ``code`` parameter in the query and ``state``, if you've included it in the authorization link: .. code-block:: https://yourwebsite.com/code ?code=OB17QWWpAaJJlyjebGfC3pSMyOz7gG5POFFp &state=635bc9bc-2915-41d9-9b7b-16f2e86757af Use authorization code to get a token ====================================== The second step in this flow is to use the authorization code to get an access token and refresh token. To get the tokens, send a http POST request to ``https://exbo.net/oauth/token`` with following x-www-form-urlencoded parameters in the body: .. list-table:: :header-rows: 1 :class: tight-table :widths: 1 1 1 10 * - Parameter - Required - Example - Description * - ``client_id`` - Yes - ``30`` - Unique identifier for your application. You will receive it once your application has been :doc:`approved ` * - ``client_secret`` - Yes - ``n0ns6h6d9xtfx9igtuahp3k0fyq2b5zj8l2770i4`` - Secret for your application. Same as client id, you will receive it once your application has been :doc:`approved ` * - ``code`` - Yes - ``OB17QWWpAaJJlyjebGfC3pSMyOz7gG5POFFp`` - Authorization code acquired in the previous step. * - ``grant_type`` - Yes - ``authorization_code`` - Must be set to ``authorization_code`` * - ``redirect_uri`` - Yes - ``https://youwebsite.com/code`` - Your app's registered redirect uri If the request succeeds, it returns an access token and refresh token in json format: .. code-block:: json { "token_type": "Bearer", "expires_in": 31536000, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwic3ViIjoiMSIsIm5iZiI6MTY3Mzc5NzgzOCwiZXhwIjo0ODI3Mzk3ODM4LCJpYXQiOjE2NzM3OTc4MzgsImp0aSI6IjJlamRwOG54a3A1djRnZWdhbWVyeWlkMW5ic24zZDhpZ2oyejgzem1vMDYzNjNoaXFkNWhwOTY1MHZwdWh4OXEybXBmd2hnbnUxNHR5cmp2In0.Ocw4CzkkuenkAOjkAR1RuFgLqix7VJ-8vWVS3KAJ1T3SgIWJG145xqG2qms99knu5azn_oaoeyMOXhyG_fuMQFGOju317GiS6pAXAFGOKvxcUCfdpFcEHO6TWGM8191-tlfV-0rAqCi62gprKyr-SrUG3nUJhv6XKegja_vYVujRVx0ouAaDvDKawiOssG5If_hXGhdhnmb3_7onnIc4hFsm4i9QVkWXe8GO6OsS999ZIX0ClNhTk2kKKTl2dDVIiKha_HB1aghm_LOYoRgb3i3B_DH4UO312rHYR5I4qO43c8x-TW7NwovItDSzhiCmcxZuUUeAUF3yFr5ovaR4fMj1LEy3y3V2piQDKPwmBOpI9S6OzWUIBJYcRYlT2HIrWCRc0YvM7AOGoxcH2Gf4ncqcF_M8fw7IMKf3pdnuxf1EbdEpzOapBD1Pw065em-U8PN4LVzw9lhIHx_Yj69qaFEx7Bhw3BCwsrx-o9hgg7T1TOV6kF11YfR99lIuj9z96XBLg5ipt-M_j7nHRoHWhM0Rc6uLIKPg0In0xYkybSfWG6v3Hs6kwgB7wkqpXpoVQltJvlqjtlf9Pp4zmkqlWQHx9as4xsgoTAQyCgaC0kisICNC58_g3QrJAfoFXW68x-OHlRKCAPqoR9V-0cVs-B83szaFmsEGegAttFLlDhE", "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwibmJmIjoxNjczNzk3ODM4LCJleHAiOjQ4MjczOTc4MzgsImlhdCI6MTY3Mzc5NzgzOCwianRpIjoiYXhwbzAzenJwZWxkMHY5dDgzdzc1N2x6ajl1MmdyeHVodXVlb2xsZ3M2dml1YjVva3NwZTJ3eGFrdjJ1eWZxaDU5ZDE2ZTNlN2FqdW16Z3gifQ.ZNSsvwAX72xT5BzLqqYABuH2FGbOlfiXMK5aYO1H5llG51ZjcPvOYBDRR4HUoPZVLFY8jyFUsEXNM7SYz8qL9ePmLjJl6pib8FEtqVPmf9ldXvKkbaaaSp4KkJzsIEMY_Z5PejB2Vr-q-cL13KPgnLGUaSW-2X_sHPN7VZJNMjRgjw4mPiRZTe4CEpQq0BEcPrG6OLtU5qlZ6mLDJBjN2xtK0DI6xgmYriw_5qW1mj1nqF_ewtUiQ1KTVhDgXnaNUdkGsggAGqyicTei0td6DTKtnl3noD5VkipWn_CwSqb2Mhm16I9BPfX_d5ARzWrnrwPRUf6PA_7LipNU6KkkW0mhZfmwEPTm_sXPus0mHPENoVZArdFT3L5sOYBcpqwvVIEtxRUTdcsKp-y-gSzao5muoyPVoCc2LEeHEWx0cIi9spsZ46SPRQpN4baVFp7y5rp5pjRsBKHQYUJ0lTmh1_vyfzOzbtNN2v6W_5w9JTLrN1U6fhmifvKHppFSEqD6DameL1TC59kpIdufRkEU9HE4O-ErEf1GuJFRx-Dew6XDvb_ExhvEqcw31yNvKzpVqLYJfLazqn6tUbVuAiPwpy6rP9tYO2taT1vj5TGn_vxwDu9zoLWe796tFMPS-kmbCglxB5C9L4EbpfWNbWxYjUkTvjT2Ml9OnrB0UbYo1jI" } Received access token will expire after some time. When it does, you should use refresh token to get a new access token. Refreshing a User Token ======================= To refresh a user access token, send a http POST request to ``https://exbo.net/oauth/token`` with following x-www-form-urlencoded parameters in payload body: .. list-table:: :header-rows: 1 :class: tight-table :widths: 1 1 1 10 * - Parameter - Required - Example - Description * - ``client_id`` - Yes - ``30`` - Unique identifier for your application. You will receive it once your application has been :doc:`approved ` * - ``client_secret`` - Yes - ``n0ns6h6d9xtfx9igtuahp3k0fyq2b5zj8l2770i4`` - Secret for your application. Same as client id, you will receive it once your application has been :doc:`approved ` * - ``grant_type`` - Yes - ``refresh_token`` - Must be set to ``refresh_token`` * - ``refresh_token`` - Yes - ``eyJ0eXAiOiJKV1<...>kmbCglxB5C9L4EbpfWNbWxYjUkTvjT2Ml9OnrB0UbYo1jI`` - A refresh token acquired along with now expired access token * - ``scope`` - Yes - ```` - Scope required by your application. This parameter is designed for future use. You must specify this parameter, but leave it empty for now. Requesting User Information =========================== After you've acquired user access token, you can make a request to authentication server to retrieve additional information about user. For example, her login. To do that, send a http GET request to ``https://exbo.net/oauth/user`` with user access token in header ``Authorization``. An example of such request: .. code-block:: curl -X GET https://exbo.net/oauth/user -H "Authorization: Bearer $userToken" An example response on success: .. code-block:: json { "id": 90102, "uuid": "1d78bf8c-58b8-4bec-bf38-a0bb9eb17d9f", "login": "Test-1", "display_login": null, "distributor": "EXBO", "distributor_id": null } Application Auth Method ~~~~~~~~~~~~~~~~~~~~~~~ If your app only needs to access resources that don't require user permission, use an application auth method. If your app also needs to access resources that require user permission, use a user access token, which can also be used for resources that accept application auth method. There are two possible ways to authorize your application Client Credentials Grant ========================= This is a traditional OAuth flow which will result in access token for your application. Should be used if you want to follow general approach as defined by OAuth specification. To get an access token, send a http POST request to ``https://exbo.net/oauth/token`` with following x-www-form-urlencoded parameters in payload body: .. list-table:: :header-rows: 1 :class: tight-table :widths: 1 1 1 10 * - Parameter - Required - Example - Description * - ``client_id`` - Yes - ``30`` - Unique identifier for your application. You will receive it once your application has been :doc:`approved ` * - ``client_secret`` - Yes - ``n0ns6h6d9xtfx9igtuahp3k0fyq2b5zj8l2770i4`` - Secret for your application. Same as client id, you will receive it once your application has been :doc:`approved ` * - ``grant_type`` - Yes - ``client_credentials`` - Must be set to ``client_credentials`` * - ``scope`` - Yes - ```` - Scope required by your application. This parameter is designed for future use. You must specify this parameter, but leave it empty for now. If the request succeeds, it returns an access token in json format. .. code-block:: { "token_type": "Bearer", "expires_in": 31536000, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwibmJmIjoxNjczNzk3ODM4LCJleHAiOjQ4MjczOTc4MzgsImlhdCI6MTY3Mzc5NzgzOCwianRpIjoiYXhwbzAzenJwZWxkMHY5dDgzdzc1N2x6ajl1MmdyeHVodXVlb2xsZ3M2dml1YjVva3NwZTJ3eGFrdjJ1eWZxaDU5ZDE2ZTNlN2FqdW16Z3gifQ.ZNSsvwAX72xT5BzLqqYABuH2FGbOlfiXMK5aYO1H5llG51ZjcPvOYBDRR4HUoPZVLFY8jyFUsEXNM7SYz8qL9ePmLjJl6pib8FEtqVPmf9ldXvKkbaaaSp4KkJzsIEMY_Z5PejB2Vr-q-cL13KPgnLGUaSW-2X_sHPN7VZJNMjRgjw4mPiRZTe4CEpQq0BEcPrG6OLtU5qlZ6mLDJBjN2xtK0DI6xgmYriw_5qW1mj1nqF_ewtUiQ1KTVhDgXnaNUdkGsggAGqyicTei0td6DTKtnl3noD5VkipWn_CwSqb2Mhm16I9BPfX_d5ARzWrnrwPRUf6PA_7LipNU6KkkW0mhZfmwEPTm_sXPus0mHPENoVZArdFT3L5sOYBcpqwvVIEtxRUTdcsKp-y-gSzao5muoyPVoCc2LEeHEWx0cIi9spsZ46SPRQpN4baVFp7y5rp5pjRsBKHQYUJ0lTmh1_vyfzOzbtNN2v6W_5w9JTLrN1U6fhmifvKHppFSEqD6DameL1TC59kpIdufRkEU9HE4O-ErEf1GuJFRx-Dew6XDvb_ExhvEqcw31yNvKzpVqLYJfLazqn6tUbVuAiPwpy6rP9tYO2taT1vj5TGn_vxwDu9zoLWe796tFMPS-kmbCglxB5C9L4EbpfWNbWxYjUkTvjT2Ml9OnrB0UbYo1jI" } Secret Based Authentication =========================== Client credentials grant flow by OAuth specification requires your to obtain special application token before you're able to access any APIs. This introduces additional state which your application has to manage. To make it a bit easier to implement application which don't read user data, you can entirely avoid obtaining application access tokens and authenticate all your requests by including your application id and secret directly in the following headers. .. list-table:: :header-rows: 1 :class: tight-table :widths: 1 1 10 * - Header - Example - Description * - ``Client-Id`` - ``30`` - Unique identifier for your application. You will receive it once your application has been :doc:`approved ` * - ``Client-Secret`` - ``n0ns6h6d9xtfx9igtuahp3k0fyq2b5zj8l2770i4`` - Secret for your application. Same as client id, you will receive it once your application has been :doc:`approved ` For example, we can read list of clans from the demo API using the following request: .. code-block:: curl -X GET https://dapi.stalcraft.net/EU/clans -H "Client-Id: 1" -H "Client-Secret: E98cm6J9NNjTQopph0c2eIXNKafg4R1Cjz0TZh2D" Validating Tokens ~~~~~~~~~~~~~~~~~ Stalcraft API utilizes JSON Web Tokens format, meaning both access tokens and refresh tokens are valid JWT objects. They can be validated by checking their signature and their payload can be decoded to find out when it was issued, when it expires, and the user that authorized that token. For example, given the following user access token: .. code-block:: json eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwic3ViIjoiMSIsIm5iZiI6MTY3Mzc5NzgzOCwiZXhwIjo0ODI3Mzk3ODM4LCJpYXQiOjE2NzM3OTc4MzgsImp0aSI6IjJlamRwOG54a3A1djRnZWdhbWVyeWlkMW5ic24zZDhpZ2oyejgzem1vMDYzNjNoaXFkNWhwOTY1MHZwdWh4OXEybXBmd2hnbnUxNHR5cmp2In0.Ocw4CzkkuenkAOjkAR1RuFgLqix7VJ-8vWVS3KAJ1T3SgIWJG145xqG2qms99knu5azn_oaoeyMOXhyG_fuMQFGOju317GiS6pAXAFGOKvxcUCfdpFcEHO6TWGM8191-tlfV-0rAqCi62gprKyr-SrUG3nUJhv6XKegja_vYVujRVx0ouAaDvDKawiOssG5If_hXGhdhnmb3_7onnIc4hFsm4i9QVkWXe8GO6OsS999ZIX0ClNhTk2kKKTl2dDVIiKha_HB1aghm_LOYoRgb3i3B_DH4UO312rHYR5I4qO43c8x-TW7NwovItDSzhiCmcxZuUUeAUF3yFr5ovaR4fMj1LEy3y3V2piQDKPwmBOpI9S6OzWUIBJYcRYlT2HIrWCRc0YvM7AOGoxcH2Gf4ncqcF_M8fw7IMKf3pdnuxf1EbdEpzOapBD1Pw065em-U8PN4LVzw9lhIHx_Yj69qaFEx7Bhw3BCwsrx-o9hgg7T1TOV6kF11YfR99lIuj9z96XBLg5ipt-M_j7nHRoHWhM0Rc6uLIKPg0In0xYkybSfWG6v3Hs6kwgB7wkqpXpoVQltJvlqjtlf9Pp4zmkqlWQHx9as4xsgoTAQyCgaC0kisICNC58_g3QrJAfoFXW68x-OHlRKCAPqoR9V-0cVs-B83szaFmsEGegAttFLlDhE We can use `JWT Debugger `_ to look into its payload: .. code-block:: json { "aud": "1", // id of the application for which this token is intended for "sub": "1", // the user which authorized this token "nbf": 1673797838, "exp": 4827397838, // expiration time of this token, this token is valid for 100 years "iat": 1673797838, // time when this token was issued "jti": "2ejdp8nxkp5v4gegameryid1nbsn3d8igj2z83zmo06363hiqd5hp9650vpuhx9q2mpfwhgnu14tyrjv" // unique identifier of the token } Stalcraft API will check token's payload on API request and will return status ``401`` if the token is no longer valid. Note that token can become invalid for reasons other than the token expiring. For example, the user may disconnect the integration or the token may become revoked.