# Access Token Handling

The SnapOdds SDK requires a valid access token to be provided in order to communicate with the Snapscreen API, which uses the OAuth 2.0 authentication mechanism.&#x20;

Our customers are provided with a `Client ID` and `Secret` which must be used to retrieve the access token from the API endpoint described below:

## Grants an access token to an anonymous user.

<mark style="color:green;">`POST`</mark> `https://api.us.snapscreen.com/oauth/token`

#### Request Body

| Name                                             | Type   | Description                                                     |
| ------------------------------------------------ | ------ | --------------------------------------------------------------- |
| client\_id<mark style="color:red;">\*</mark>     | String | The client identifier specific to the customer.                 |
| client\_secret<mark style="color:red;">\*</mark> | String | The client secret.                                              |
| grant\_type<mark style="color:red;">\*</mark>    | String | The requested access grant type, should be set to  "anonymous". |
| device\_fingerprint                              | String | Unique device fingerprint.                                      |

{% tabs %}
{% tab title="200: OK An access token and it requisites." %}

```json
{
  access_token: string,
  token_type: string,
  refresh_token: string,
  expires_in: number (long),
  scope: string
}
```

{% endtab %}

{% tab title="401: Unauthorized A request lacks valid authentication credentials for the requested resource. " %}

```json
{
  error: string,
  error_description: string
}
```

{% endtab %}

{% tab title="403: Forbidden The server refuses to authorize request." %}

```json
{
  error: string,
  error_description: string
}
```

{% endtab %}

{% tab title="400: Bad Request A request is not well formatted." %}

```json
{
  error: string,
  error_description: string
}
```

{% endtab %}

{% tab title="500: Internal Server Error The server encountered an unexpected condition that prevented it from fulfilling the request." %}

```json
{
  error: string,
  error_description: string
}
```

{% endtab %}
{% endtabs %}

Below is an example of the HTTP request using `curl` to receive an access token:

```bash
curl -d "client_id=YourClientId&client_secret=YourClientSecret&grant_type=anonymous"  https://api.us.snapscreen.com/oauth/token
```

Having the access token retrieval system implemented on the client side is unsafe and strongly discouraged, as credentials are available in plain text and could easily be stolen. Therefore SnapOdds recommends implementation of this logic on the server side.&#x20;

For the implementation to function, a REST API endpoint must be provided from which the client can request the access token. On the server side, the access token will be fetched from the Snapscreen API, stored in the current HTTP session, and then returned to the browser.&#x20;

To further improve security, we also recommend using the [CSRF token](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_\(CSRF\)_Prevention_Cheat_Sheet#Synchronizer_.28CSRF.29_Tokens) technique to protect this resource. If you have other security protection mechanisms available in your Web Application, then we highly recommend using them as well.

### Fetch AccessToken Example

Let us assume a REST API endpoint has been created using the path `'/token'`. The next required step is to direct this endpoint to the SnapOdds SDK in the form of an access token provider, which is `function` that when executed will return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) of the whole access token returned from the Snapscreen API.&#x20;

Enclosed below is a snippet of a basic implementation of the access token provider.&#x20;

```javascript
function fetchAccessTokenFromApi() {
  return fetch('/token', { mode: 'cors', cache: 'no-cache' })
    .then((response) => response.json());
}
```

{% hint style="info" %}
**Note**: The access token provider must return a standard [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) (not any equivalent like [AngularJS $q](https://docs.angularjs.org/api/ng/service/$q) or other custom promise libraries like [Kris Kowal's Q](https://github.com/kriskowal/q)). The SDK is built as angular element and relies on [zone.js](https://github.com/angular/angular/tree/master/packages/zone.js) for change detection, so only browser native async methods are recognized.&#x20;
{% endhint %}
