How to implement a custom_access_token_expires_in method with Doorkeeper?

856 views Asked by At

I have a rails 7 application with its own api. I am using Doorkeeper gem to implement authorizing external parties to be able to use the API.

So far I have gotten the Doorkeeper gem working with the following workflow:

  • User creates a new application with Doorkeeper::Application and receives a client_id and client_secret.
  • User logs in using the endpoint /api/v1/oauth/token and with the follow params:
{
    "grant_type": "password",
    "email": "[email protected]",
    "password": "password",
    "client_id": "laksjdflkajfljlkjdsalkjdas",
    "client_secret": "dasldjaskdjaslkdjaslkdjalk",
}  

responds with:

{
    "access_token": "sdadasdasdasdasdasdasd",
    "token_type": "Bearer",
    "expires_in": 7200,
    "created_at": 1662501786
}

Question: How do I structure my Doorkeeper initializer to have an access token that expires in 2 hours and another access token that expires in 1 year?

I create the access token here:

module DoorkeeperRegisterable
  extend ActiveSupport::Concern

  #   def generate_refresh_token
  #     loop do
  #       token = SecureRandom.hex(32)
  #       break token unless Doorkeeper::AccessToken.exists?(refresh_token: token)
  #     end
  #   end

  def render_user(user, client_app, token_type = 'Bearer')
    access_token = Doorkeeper::AccessToken.create(
      resource_owner_id: user.id,
      application_id: client_app.id,
      #   refresh_token: generate_refresh_token,
      expires_in: Doorkeeper.configuration.access_token_expires_in.to_i,
      scopes: ''
    )

    {
      id: user.id,
      access_token: access_token.token,
      token_type:,
      expires_in: access_token.expires_in,
      #   refresh_token: access_token.refresh_token,
      created_at: access_token.created_at.to_time.to_i
    }
  end
end

I can change the value of access_token_expires_in 2.hours in config/initializers/doorkeeper.rb but cannot get a second option to work.

I tried doing this in config/initializers/doorkeeper.rb:

custom_access_token_expires_in do |context|
 return 1.year if context
end

and then trying to access it in the concern by doing:

Doorkeeper.configuration.custom_access_token_expires_in.to_i

but cannot get it to work. I dont think I am understanding context in the initilizer file correctly. No matter what I try it defaults to the value of access_token_expires_in.

The goal I would like to acheive is to have access_token_expires_in 2.hours for when the user tries getting a token without a password. And when a user sends a password param with a correct password, I somehow use custom_access_token_expires_in to send an access token that takes longer to expire. This is probably me misunderstanding how Doorkeeper works but if anyone is able to help me build out this workflow I would greatly appreciate it.

1

There are 1 answers

0
Owen Roth On

Figured it out. I was confusing endpoints. The concerned I linked was for my create user endpoint.

All I needed to do was add this to doorkeeper.rb initializer:

  custom_access_token_expires_in do |context|
    if context.grant_type == "password"
      2.years
    else
      1.day
    end
  end

Essentially this checks the params for a valid password grant type. If the grant type is valid (and so is the password) the access token will expire in 2 years, otherwise if no password grant type is passed by the request is authorized it will be one day