Skip to content

Enable Refresh Token flow

Nikita Bulai edited this page Nov 25, 2016 · 1 revision

Refresh tokens are credentials used to obtain access tokens. For more information about how they work, check out the OAuth 2 section about refresh tokens.

Note that Refresh Tokens associated with particular client can be refreshed only from that client.

Take a look at the OAuth2 specification for Refresh Token flow:

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

Configuration

To enable refresh tokens in your application you need to change Grape::OAuth2 configuration:

Grape::OAuth2.configure do |config|
  config.allowed_grant_types = %w(... refresh_token) # ... - your configured allowed grant types

  config.issue_refresh_token = true # will generate refresh tokens
  
  # Process Access Token that was used for the Refresh Token Flow (default is :nothing).
  # Could be a symbol (Access Token instance must respond to it)
  # or block with refresh token as an argument.
  config.on_refresh = :nothing
end

This is basically everything you need to do. From now on, your provider will be issuing refresh tokens. This means that client applications will be able to request new access tokens in case the old ones have expired.

Protection against replay attacks

If you want to do something with the original Access Token that was used with the Refresh Token Flow, then you need to setup on_refresh configuration option. By default Grape::OAuth2 gem does nothing on token refresh and that option is set to :nothing. You can set it to the symbol (in that case Access Token instance must respond to it) or block. Look at the examples:

Grape::OAuth2.configure do |config|
  # ...
  
  config.on_refresh = :destroy # will call :destroy method (`refresh_token.destroy`)
end
Grape::OAuth2.configure do |config|
  # ...
  
  config.on_refresh do |refresh_token|
    refresh_token.destroy
    
    MyAwesomeLogger.info("Token ##{refresh_token.id} was destroyed on refresh!")
  end
end

Testing

# Example uses ActiveRecord ORM
client = Client.first
access_token = client.access_tokens.first

RestClient.post 'http://localhost:3000/api/oauth/token',
  grant_type: 'refresh_token',
  refresh_token: token.refresh_token,
  client_id: client.key,
  client_secret: client.secret

#=> { "access_token": "...", "expires_in": 7200, refresh_token: "...", "token_type": "bearer" }