Skip to content

User tokens

Justin Forest edited this page Apr 26, 2023 · 17 revisions

User tokens are OAuth access tokens that identify a particular user and let an application act on behalf of that user, doing anything the user can do. For an app to get a user token, the following workflow is used, similar to other OAuth 2 sites:

  1. Send a user to the authorization form.
  2. Handle the redirect callback.
  3. Request the tokens.
  4. Refreshing tokens
  5. Valid scopes

You can also use the RFC 8414 discovery protocol implemented here.

Showing the authorization form

The URL of the authorization form is constructed like this:

https://www.redgifs.com/authorize
 ?response_type=code
 &client_id=foobar
 &state=custom-payload
 &scope=upload
 &redirect_uri=http://127.0.0.1/auth/callback

The following arguments are used:

  • response_type: this can only be "code", which means the authorization code flow will be used. No other flows are supported at this moment.
  • client_id: this is part of your client credentials.
  • state: some custom data that will be passed back to your site, which helps you match responses to requests. Like, a local user id.
  • scope: what your app needs to do, e.g. "read upload". See this list for valid values.
  • redirect_uri: where to send the user back on success on error.

When the page opens, the user will be asked to log in, if needed, then to confirm or reject the authorization. On success, the user is redirected to page specified with redirect_uri.

Handling the response

When the user confirms or rejects authorization, they are redirected to the URL, specified in the redirect_uri, with the following parameters added:

  • code: a unique single use code that can be exchanged for an access token, see below.
  • state: the custom payload that was specified in the authorization URL.
  • error: a code describing why the process failed. Optional. Either code, or this.

Example of a successful redirect URL:

http://127.0.0.1/auth/callback?code=XSZf3cpKpwPyPgR373gzqB&state=alice

You can use the value of code to get the tokens, and the value of state to know which local user the token belongs to.

In case of failure, the redirect URL will look like this:

http://127.0.0.1/auth/callback?error=deny&state=alice

Getting the tokens

To exchange the authorization code for access and refresh tokens, the following request needs to be sent to the API, according to RFC 6749 (formatting added for readability):

POST /v2/oauth/token
Host: api.redgifs.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=XSZf3cpKpwPyPgR373gzqB
&redirect_uri=http://127.0.0.1/auth/callback
&client_id=foobar
&client_secret=8zNHckswBbfJC3U5seU9x9

Note that code is the code that you received in your callback, and redirect_uri and client_id must be identical to those used in the authorization form URL, otherwise the request will fail. The app must send client credentials with this request.

Response on success:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
 "token_type": "bearer",
 "expires_in": 86400,
 "refresh_token": "JsNm2Q6NQrfRm9oNrFe3zV"
}

You can use the access_token value to perform any API requests on behalf of the user, like, upload videos. The token will expire soon (24 hours in the above example). Then the app will need to refresh the token.

Refreshing tokens

When the access token expires, you need a new one. Use the previously stored refresh token to request a new pair, with a request like this:

POST /v2/oauth/token
Host: api.redgifs.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=JsNm2Q6NQrfRm9oNrFe3zV
&client_id=foobar
&client_secret=8zNHckswBbfJC3U5seU9x9

Note that the app needs to send the client credentials with this request. Successful response looks identical to the initial response for getting the tokens:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
 "token_type": "bearer",
 "expires_in": 86400,
 "refresh_token": "JsNm2Q6NQrfRm9oNrFe3zV"
}

Note that the access_token will be new, and the refresh_token might also change, so the app should update the local copy.

Scopes

  • read: read-only access to user's contents.
  • upload: upload new gifs.