### Run local engine server Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Starts the local development server for the Doorkeeper engine. ```bash bundle install bundle exec rake doorkeeper:server ``` -------------------------------- ### Run standard development tasks Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/AGENTS.md Commands to install dependencies, run the full test suite, and execute linting. ```bash bundle install bundle exec rake spec bundle exec rubocop ``` -------------------------------- ### Install Ruby Dependencies Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/CONTRIBUTING.md Install project dependencies using Bundler. ```ruby bundle install ``` -------------------------------- ### Execute targeted development commands Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/AGENTS.md Commands for running specific test files or starting the local development server. ```bash bundle exec rspec spec/path/to/file_spec.rb bundle exec rake doorkeeper:server ``` -------------------------------- ### Install Redis Throttle Gem Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Rate-limit-with-Redis Add the redis-throttle gem to your Gemfile and run bundle install. ```ruby gem 'redis-throttle', git: 'git@github.com:andreareginato/redis-throttle.git' ``` -------------------------------- ### GET /oauth/authorize/native Endpoint Example Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows how to retrieve an authorization code using the native authorization endpoint. It includes a curl command and the expected HTML output. ```bash curl http://localhost:3000/oauth/authorize/native?code=fd0847dbb559752d932dd3c1ac34ff98d27b11fe2fea5a864f44740cd7919ad0 ``` ```html

Authorization code:

fd0847dbb559752d932dd3c1ac34ff98d27b11fe2fea5a864f44740cd7919ad0 ``` ```ruby Started GET "/oauth/authorize/native" for 127.0.0.1 at 2014-02-26 17:42:14 -0500 Processing by Doorkeeper::AuthorizationsController#show as */* Parameters: {"code"=>"fd0847dbb559752d932dd3c1ac34ff98d27b11fe2fea5a864f44740cd7919ad0"} User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" IS NULL LIMIT 1 Rendered /Users/dclo/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/bundler/gems/doorkeeper-e0c826aff1ec/app/views/doorkeeper/authorizations/show.html.erb within layouts/application (4.8ms) Rendered layouts/_header.html.erb (0.4ms) Rendered layouts/_flash.html.erb (0.5ms) ``` -------------------------------- ### Client Credentials Flow with Basic Auth Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated Example of an HTTP POST request for the Client Credentials flow using the Authorization Basic header. ```http POST /oauth/token Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=client_credentials ``` -------------------------------- ### Register User Controller Example Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Auto-sign-up-after-registration This controller action handles user registration. It creates a new user, logs them in upon successful save, and redirects to a specified path if provided. This ensures a smooth transition from registration to the user's intended destination. ```ruby # in register user controller def create user = User.new(permitted_user_params) if user.save login(user) if params[:after_login_path] # this you need to make sure to pass from links to initial redirect path redirect_to(params[:after_login_path]) end else # handle invalid user end end ``` -------------------------------- ### Curl Command to Get Token Info Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This curl command demonstrates how to retrieve details about an access token. ```bash curl -H "Authorization: Bearer 53cff8f4a549beb1c38704158b0f6608a2382f094b6947ecc35c2eed4146a17c" \ localhost:3000/oauth/token/info ``` -------------------------------- ### Login Controller Example Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Auto-sign-up-after-registration This controller action handles user login. It includes logic to find the user, log them in, and redirect to a specified path if provided. This is a common pattern for handling user authentication after a successful login. ```ruby # in login controller def login user = the_code_to_login_user # varies from app to app if user login(user) if params[:after_login_path] # this you need to make sure to pass from links to initial redirect path redirect_to(params[:after_login_path]) end else # handle bad username and password end end ``` -------------------------------- ### Client Credentials Flow with Request Body Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated Example of an HTTP POST request for the Client Credentials flow using client credentials in the request body. ```http POST /oauth/token grant_type=client_credentials&client_id=...&client_secret=... ``` -------------------------------- ### Server Output for Token Info Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows the server logs when a GET request is made to the /oauth/token/info endpoint. ```log Started GET "/oauth/token/info" for 127.0.0.1 at 2015-08-24 17:03:32 -0700 Processing by Doorkeeper::TokenInfoController#show as */* Doorkeeper::AccessToken Load (0.3ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = ? LIMIT 1 [["token", "bea06cb4f681e04f5a3bbfe699ad1b7e8cb40c2a57f974370da5f537d71509be"]] Completed 200 OK in 2ms ``` -------------------------------- ### Access Token Response Example Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Authorization-Code-Flow The expected JSON response when successfully requesting an access token, containing the `access_token`, `token_type`, `expires_in`, and `refresh_token`. ```json { "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1" } ``` -------------------------------- ### Server Output for Listing Authorized Applications Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This log shows the server-side processing for a GET request to /oauth/applications, including the database query for applications and the rendering of the index view. ```log Started GET "/oauth/applications" for 127.0.0.1 at 2014-02-26 18:01:41 -0500 Processing by Doorkeeper::ApplicationsController#index as */* Doorkeeper::Application Load (0.1ms) SELECT "oauth_applications".* FROM "oauth_applications" Rendered doorkeeper/applications/index.html.erb within layouts/application (3.6ms) Rendered layouts/_header.html.erb (0.0ms) Rendered layouts/_flash.html.erb (0.0ms) Completed 200 OK in 18ms (Views: 15.8ms | ActiveRecord: 0.7ms) ``` -------------------------------- ### Request Access Token using Client Credentials Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Client-Credentials-flow Demonstrates how to obtain an access token using the client credentials flow in Ruby. This example uses `rest-client` to POST to the token endpoint with client ID and secret in the parameters. ```ruby require 'rest-client' require 'json' client_id = '4ea1b...' client_secret = 'a2982...' response = RestClient.post 'http://localhost:3000/oauth/token', { grant_type: 'client_credentials', client_id: client_id, client_secret: client_secret } ``` -------------------------------- ### GET /oauth/token/info Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples Shows details about the token used for authentication. Handles both valid and invalid tokens. ```APIDOC ## GET /oauth/token/info ### Description Shows details about the token used for authentication. ### Method GET ### Endpoint /oauth/token/info ### Parameters #### Header Parameters - **Authorization** (string) - Required - Bearer token for authentication. ### Request Example ```bash curl -H "Authorization: Bearer 53cff8f4a549beb1c38704158b0f6608a2382f094b6947ecc35c2eed4146a17c" \ localhost:3000/oauth/token/info ``` ### Response #### Success Response (200) - **resource_owner_id** (integer) - The ID of the resource owner. - **scopes** (array) - An array of scopes associated with the token. - **expires_in_seconds** (integer) - The remaining time in seconds until the token expires. - **application** (object) - Details about the application associated with the token. - **uid** (string) - The unique identifier of the application. - **created_at** (integer) - The timestamp when the token was created. #### Response Example (Success) ```json { "resource_owner_id":1, "scopes":[], "expires_in_seconds":7178, "application":{"uid":null}, "created_at":1440460991 } ``` #### Error Response (401) - **error** (string) - Indicates the type of error, e.g., "invalid_token". - **error_description** (string) - A description of the error, e.g., "The access token is invalid". - **state** (string) - The state parameter, if provided. #### Response Example (Token Not Found) ```json { "error":"invalid_token", "error_description":"The access token is invalid", "state":"unauthorized" } ``` ### Server Output Example (Success) ``` Started GET "/oauth/token/info" for 127.0.0.1 at 2015-08-24 17:03:32 -0700 Processing by Doorkeeper::TokenInfoController#show as */* Doorkeeper::AccessToken Load (0.3ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = ? LIMIT 1 [["token", "bea06cb4f681e04f5a3bbfe699ad1b7e8cb40c2a57f974370da5f537d71509be"]] Completed 200 OK in 2ms ``` ### Server Output Example (Token Not Found) ``` Started GET "/oauth/token/info" for 127.0.0.1 at 2015-08-24 17:06:49 -0700 Processing by Doorkeeper::TokenInfoController#show as */* Doorkeeper::AccessToken Load (0.1ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = ? LIMIT 1 [["token", "bea06cb4f681e04f5a3bbfe699ad1b7e8cb40c2a57f974371509be"]] Completed 401 Unauthorized in 1ms ``` ``` -------------------------------- ### POST /oauth/authorize Endpoint Example Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet demonstrates how to obtain an authorization code by POSTing to the authorization endpoint. It requires `response_type`, `client_id`, `client_secret`, `redirect_uri`, and `username`. The response is a redirect to the authorization code display page. ```bash curl -F response_type=code \ -F client_id=9b36d8c0db59eff5038aea7a417d73e69aea75b41aac771816d2ef1b3109cc2f \ -F client_secret=d6ea27703957b69939b8104ed4524595e210cd2e79af587744a7eb6e58f5b3d2 \ -F redirect_uri=urn:ietf:wg:oauth:2.0:oob \ -F username=user@example.com \ -X POST http://localhost:3000/oauth/authorize ``` ```html You are being redirected. ``` -------------------------------- ### Access Application Routes and Helpers Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-views When using Doorkeeper views, prefix routes and helpers belonging to your main application with `main_app`. This example shows how to conditionally render Sign In/Out links. ```erb <% if main_app.user_signed_in? %> <%= link_to "Sign Out", main_app.destroy_user_session_path, :method => 'delete' %> <% else %> <%= link_to "Sign In", main_app.new_user_session_path %> <% end %> ``` -------------------------------- ### Server Output for Authorized Applications Index Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows the server logs when a GET request is made to the /oauth/authorized_applications endpoint. ```log Started GET "/oauth/authorized_applications" for 127.0.0.1 at 2014-02-26 18:36:46 -0500 Processing by Doorkeeper::AuthorizedApplicationsController#index as */* Parameters: {"username"=>"user@example.com"} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'user@example.com' LIMIT 1 CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'user@example.com' LIMIT 1 Doorkeeper::Application Load (0.6ms) SELECT "oauth_applications".* FROM "oauth_applications" INNER JOIN "oauth_access_tokens" ON "oauth_access_tokens"."application_id" = "oauth_applications"."id" AND "oauth_access_tokens"."revoked_at" IS NULL INNER JOIN "oauth_applications" "authorized_applications_oauth_applications" ON "authorized_applications_oauth_applications"."id" = "oauth_access_tokens"."application_id" WHERE "oauth_access_tokens"."resource_owner_id" = 1 AND "oauth_access_tokens"."revoked_at" IS NULL GROUP BY oauth_applications.id,oauth_applications.name,oauth_applications.uid,oauth_applications.secret,oauth_applications.redirect_uri,oauth_applications.created_at,oauth_applications.updated_at,oauth_applications.owner_id,oauth_applications.owner_type Rendered doorkeeper/authorized_applications/index.html.erb within layouts/application (44.5ms) Rendered layouts/_header.html.erb (0.0ms) Rendered layouts/_flash.html.erb (0.0ms) Completed 200 OK in 5593ms (Views: 58.4ms | ActiveRecord: 1.8ms) ``` -------------------------------- ### Install Doorkeeper Gem Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Add the Doorkeeper gem to your Ruby project's Gemfile. ```ruby gem 'doorkeeper' ``` -------------------------------- ### Make API Request Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Use the obtained access token to make requests to the protected API endpoints of the OAuth2 provider. This example fetches 'profiles' resources. ```ruby response = token.get('/api/v1/profiles.json') JSON.parse(response.body) # => [ { "username": "something", ... } ] ``` -------------------------------- ### Basic Authentication with Ruby RestClient Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Enable-Basic-authorization-for-access-tokens Example of using Basic authentication with Ruby's `RestClient` library. The access token is Base64 encoded and included in the `Authorization` header. ```ruby RestClient.get 'http://localhost:3000/api/v1/profiles.json', { 'Authorization' => "Basic #{Base64.encode64("#{token}:")}" } ``` -------------------------------- ### Basic Authentication with curl Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Enable-Basic-authorization-for-access-tokens Example of using Basic authentication with `curl` to access an API endpoint. The access token is passed as the username, and the password field is left empty. ```sh token=ec4826413c3b9649d8f6b883972a0f632576d879e3f65ae1fd5448d6e0bf327d curl -u "$token:" http://localhost:3000/api/v1/profiles.json ``` ```sh curl "http://$token:@localhost:3000/api/v1/profiles.json" ``` -------------------------------- ### Password Grant Request Parameters Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Resource-Owner-Password-Credentials-flow Example of the POST request parameters sent to the OAuth provider's /oauth/token endpoint for the password grant type. ```json { "client_id": "the_client_id", "client_secret": "the_client_secret", "grant_type": "password", "username": "user@example.com", "password": "sekret" } ``` -------------------------------- ### Test Password Credentials Flow - Success Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Example of an authentication test for the Resource Owner Password Credentials flow using RSpec and Steak. Verifies successful token acquisition. ```ruby require 'acceptance/acceptance_helper' feature 'OAuth authorization' do let(:app) { create(:application) } let(:user) { create(:user) } scenario 'auth ok' do client = OAuth2::Client.new(app.uid, app.secret) do |b| b.request :url_encoded b.adapter :rack, Rails.application end token = client.password.get_token(user.email, user.password) token.should_not be_expired end end ``` -------------------------------- ### Custom Daily Rate Limit Middleware Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Rate-limit-with-Redis Subclass Rack::RedisThrottle::Daily to define custom rate limiting rules. This example sets the client identifier to the user ID and dynamically determines the rate limit per user. ```ruby # /lib/middlewares/daily_rate_limit require 'rack/redis_throttle' class DailyRateLimit < Rack::RedisThrottle::Daily def call(env) @user_rate_limit = user_rate_limit(env) super end def client_identifier(request) @user_rate_limit.respond_to?(:_id) ? @user_rate_limit._id : 'user-unknown' end def max_per_window(request) @user_rate_limit.respond_to?(:rate_limit) ? @user_rate_limit.rate_limit : 1000 end # Rate limit only requests sending the access token def need_protection?(request) request.env.has_key?('HTTP_AUTHORIZATION') end private def user_rate_limit(env) request = Rack::Request.new(env) token = request.env['HTTP_AUTHORIZATION'].split(' ')[-1] access_token = Doorkeeper::AccessToken.where(token: token).first access_token ? User.find(access_token.resource_owner_id) : nil end end ``` -------------------------------- ### Example JSON Response for Access Token Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Interacting-as-an-OAuth-client-with-Doorkeeper This is the typical JSON response received after a successful request for an access token. It contains the access token, token type, expiration time, and refresh token. ```json {"access_token":"09ba487fc3df...", "token_type":"bearer", "expires_in":7200, "refresh_token":"8c488ab5f75d61..." } ``` -------------------------------- ### Initialize OAuth2 Client Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Set up an OAuth2 client instance with your application's credentials and the provider's site URL. This is the first step to interacting with the OAuth2 provider. ```ruby require 'oauth2' client_id = '...' # your client's id generated with rake db:setup client_secret = '...' # your client's secret redirect_uri = '...' # your client's redirect uri site = "http://localhost:3000" # your provider server, mine is running on localhost client = OAuth2::Client.new(client_id, client_secret, :site => site) ``` -------------------------------- ### Generate PKCE Migration Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-PKCE-flow Run this command to generate the necessary migration file for enabling PKCE support in Doorkeeper. This step is optional and can be performed later. ```bash bundle exec rails generate doorkeeper:pkce ``` -------------------------------- ### Build Docker Image Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/CONTRIBUTING.md Build the Docker container image for testing the Doorkeeper project. ```docker docker build --pull -t doorkeeper:test . ``` -------------------------------- ### Devise Strategy Setup for Doorkeeper Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Passing-parameters-from-a-devise-client-to-doorkeeper-(like-locale) Configure the Devise initializer to include the locale in Doorkeeper authorization parameters. ```ruby require 'omniauth/strategies/doorkeeper' config.omniauth :doorkeeper, Rails.application.secrets.doorkeeper_app_id, Rails.application.secrets.doorkeeper_app_secret, client_options: { site: Rails.application.secrets.doorkeeper_url }, authorize_params: { locale: I18n.locale }, setup: true ``` -------------------------------- ### Initialize OAuth2 Client Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Enable-Refresh-Token-Credentials Instantiate an OAuth2::Client object with your application's credentials and the provider's site URL. This is the first step in interacting with the OAuth2 provider. ```ruby client = OAuth2::Client.new(client_id, client_secret, :site => site) ``` -------------------------------- ### Update `doorkeeper_unauthorized_render_options` and `doorkeeper_forbidden_render_options` Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Starting from version 3.x, the `doorkeeper_unauthorized_render_options` and `doorkeeper_forbidden_render_options` methods now accept an `error` keyword argument. ```ruby doorkeeper_unauthorized_render_options(error: :invalid_token) ``` ```ruby doorkeeper_forbidden_render_options(error: :invalid_scope) ``` -------------------------------- ### Configure Access Token Methods Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Enable-Basic-authorization-for-access-tokens Add `:from_basic_authorization` to `access_token_methods` in the Doorkeeper initializer to enable Basic authentication. Ensure all required methods are included. ```ruby Doorkeeper.configure do access_token_methods :from_bearer_authorization, :from_basic_authorization, :from_access_token_param end ``` -------------------------------- ### Generate Doorkeeper Application Owner Migration Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-(ownership) Run this command to generate the necessary database migration for application ownership. ```bash rails generate doorkeeper:application_owner ``` -------------------------------- ### Server Output for Invalid Token Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows the server logs when a GET request is made to /oauth/token/info with an invalid token. ```log Started GET "/oauth/token/info" for 127.0.0.1 at 2015-08-24 17:06:49 -0700 Processing by Doorkeeper::TokenInfoController#show as */* Doorkeeper::AccessToken Load (0.1ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = ? LIMIT 1 [["token", "bea06cb4f681e04f5a3bbfe699ad1b7e8cb40c2a57f974371509be"]] Completed 401 Unauthorized in 1ms ``` -------------------------------- ### Generate resource indicator migration Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Run these commands to add the necessary resource column to the database. ```bash rails generate doorkeeper:resource_indicators rails db:migrate ``` -------------------------------- ### GET /oauth/authorize/native Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples Provides a page with the authorization code. This endpoint is used to display the authorization code after a successful authorization request. ```APIDOC ## GET /oauth/authorize/native ### Description Provides a page with the authorization code. ### Method GET ### Endpoint /oauth/authorize/native ### Parameters #### Query Parameters - **code** (string) - Required - The authorization code to display. ### Request Example ``` http://localhost:3000/oauth/authorize/native?code=fd0847dbb559752d932dd3c1ac34ff98d27b11fe2fea5a864f44740cd7919ad0 ``` ### Response #### Success Response (200) - **HTML page** - Contains the authorization code. #### Response Example ```html

Authorization code:

fd0847dbb559752d932dd3c1ac34ff98d27b11fe2fea5a864f44740cd7919ad0 ``` ``` -------------------------------- ### Create and Associate a Sample OAuth Application Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-(ownership) Use the Rails console to create a new OAuth application and associate it with a user. The `owner` attribute can be set to any model instance. ```ruby app = Doorkeeper::Application.new :name => 'test', :redirect_uri => 'http://test.com' app.owner = User.last # Or any owner class that you want to be associated app.save ``` -------------------------------- ### Doorkeeper Strategy Locale Handling Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Passing-parameters-from-a-devise-client-to-doorkeeper-(like-locale) In the Doorkeeper strategy, dynamically set the locale from incoming request parameters during the setup phase. ```ruby option :authorize_params, { locale: "en" } def setup_phase request.env['omniauth.strategy'].options[:authorize_params][:locale] = request.params["locale"] end ``` -------------------------------- ### Configure Client Credentials with Custom Parser and Params Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated Integrate a custom module for parsing client credentials along with fallback to parameters. ```ruby require 'my_client_credentials_awesome_parser' Doorkeeper.configure do client_credentials MyClientCredentialsAwesomeParser, :from_params end ``` -------------------------------- ### Password Grant Response - Access Token Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Resource-Owner-Password-Credentials-flow Example of the JSON response received from the OAuth provider containing the access token and related information. ```json { "access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa", "token_type": "bearer", "expires_in": 7200 } ``` -------------------------------- ### Command Output for Token Info Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows the JSON response containing details about the provided access token. ```json {"resource_owner_id":1, "scopes":[], "expires_in_seconds":7178, "application":{"uid":null}, "created_at":1440460991} ``` -------------------------------- ### Update Scope Configuration in Doorkeeper Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Starting from version 0.4.x, the scope configuration in Doorkeeper changed. Use `default_scopes` and `optional_scopes` instead of the `authorization_scopes` block. ```ruby Doorkeeper.configure do default_scopes :public optional_scopes :write, :update end ``` -------------------------------- ### Enable New Relic Transaction Tracer for TokensController Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/NewRelic-support-for-Doorkeeper::TokensController Include New Relic's controller instrumentation and add a transaction tracer for the `create` action in Doorkeeper's TokensController. ```ruby Doorkeeper::TokensController.class_eval do include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation add_transaction_tracer :create end ``` -------------------------------- ### Configure Client Credentials: Default and Basic Only Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated Configure Doorkeeper to use client credentials from both Basic header and parameters (default), or only from the Basic header. ```ruby Doorkeeper.configure do # defaults client_credentials :from_basic, :from_params # only from basic header client_credentials :from_basic end ``` -------------------------------- ### Customizing Scope and Controllers Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes Demonstrates changing the 'oauth' scope, placing routes under an additional scope, and customizing controllers for Doorkeeper. ```ruby Rails.application.routes.draw do # Change 'oauth' scope to custom one use_doorkeeper scope: 'scope' # Place routes under additional scope scope 'auth' do use_doorkeeper scope: 'endpoint' do # Customize controllers controllers authorizations: 'custom_authorizations', tokens: 'custom_authorizations', applications: 'custom_authorizations', token_info: 'custom_authorizations' as authorizations: 'custom_auth', tokens: 'custom_token', token_info: 'custom_token_info' end end # Skip some controllers use_doorkeeper do skip_controllers :tokens, :applications, :token_info end end ``` -------------------------------- ### Clone the Repository Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/CONTRIBUTING.md Clone the Doorkeeper repository to your local machine to begin development. ```git git clone git@github.com:your-username/doorkeeper.git ``` -------------------------------- ### Translate Scopes in Locale Files Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions After upgrading to version 0.4.x, scopes need to be translated in your application's locale files. This example shows the YAML structure for English translations. ```yaml en: doorkeeper: scopes: public: "Access your public data" write: "Update your data" ``` -------------------------------- ### Configure Client Authentication Strategies Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Set the order in which Doorkeeper tries different client authentication methods. This is the default configuration. ```ruby Doorkeeper.configure do # This is the default client_authentication %i[client_secret_basic client_secret_post none] end ``` -------------------------------- ### Enable Client Credentials Grant Flow Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Client-Credentials-flow Configure Doorkeeper to allow the client_credentials grant flow by adding it to the `grant_flows` array in your initializer. ```ruby # add other flows to this array if you want more to be enabled, e.g., %w{authorization_code implicit password} grant_flows ['client_credentials'] ``` -------------------------------- ### Configure Doorkeeper for Application Ownership Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-(ownership) Enable application ownership in the Doorkeeper initializer. Set `confirmation` to `false` for optional ownership or `true` to enforce it. ```ruby Doorkeeper.configure do enable_application_owner :confirmation => false end ``` -------------------------------- ### Update Application Confidentiality for Public Clients Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Starting from version 4.4.x, applications are considered private by default. Manually set `confidential` to `false` for public clients to ensure authorization works correctly. ```ruby UPDATE applications SET confidential = false WHERE id IN (SELECT id FROM applications WHERE confidential IS NULL OR confidential = true); ``` -------------------------------- ### Test Password Credentials Flow - Failure Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Example of an authentication test for the Resource Owner Password Credentials flow using RSpec and Steak. Verifies that an invalid password results in an OAuth2::Error. ```ruby require 'acceptance/acceptance_helper' feature 'OAuth authorization' do let(:app) { create(:application) } let(:user) { create(:user) } scenario 'auth nok' do client = OAuth2::Client.new(app.uid, app.secret) do |b| b.request :url_encoded b.adapter :rack, Rails.application end lambda {client.password.get_token(user.email, "123")}.should raise_error(OAuth2::Error) end end ``` -------------------------------- ### Configure Resource Owner Authentication (Basic) Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Resource-Owner-Password-Credentials-flow Set up Doorkeeper to authenticate resource owners using their username and password. This is the basic configuration for the password grant flow. ```ruby Doorkeeper.configure do resource_owner_from_credentials do |routes| User.authenticate!(params[:username], params[:password]) end end ``` -------------------------------- ### Reinstall Locale File for Doorkeeper Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions After upgrading to version 0.5.x, the locale file has been updated. Reinstall it using `rails g doorkeeper:install` and ignore other existing files to ensure proper gem functionality. ```ruby rails g doorkeeper:install ``` -------------------------------- ### Configure Client Credentials with Lambda Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated Use a lambda function to define a custom method for retrieving client credentials from the request. ```ruby Doorkeeper.configure do # custom credentials using lambda client_credentials lambda { |request| return 'uid', 'secret' } end ``` -------------------------------- ### Access Protected Resources with Client Credentials Token Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Client-Credentials-flow Shows how to use the obtained access token to make requests to protected API resources that do not require a resource owner. ```ruby RestClient.get 'http://localhost:3000/api/v1/profiles.json', { 'Authorization' => "Bearer #{token}" } # => "[{\"email\":\"tara_kertzmann@yundt.name\",\"id\":25,\"name\":\"Jorge Ward\",\"username\":\"leonor\"}, ...]" ``` -------------------------------- ### Configure OAuth2 Client with Custom Site Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Set the `site` option for the OAuth2 client when your doorkeeper routes depend on the domain. This ensures the client connects to the correct authentication server. ```ruby @oauth = OAuth2::Client.new('client_id', 'client_secret', site: 'https://login.example.org') do |b| [...] end ``` -------------------------------- ### Migrate Database for Application Ownership Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-(ownership) Execute this command after generating the migration to update your database schema. ```bash rake db:migrate ``` -------------------------------- ### Configure Default and Optional Scopes Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes Set default scopes for requests without specified scopes and define other available scopes in the Doorkeeper initializer. ```ruby Doorkeeper.configure do # if no scope was requested, this will be the default default_scopes :public # other available scopes optional_scopes :admin, :write end ``` -------------------------------- ### Register and Enable Custom Authentication Method Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Register a custom authentication class before configuration and include its name in the client_authentication array. ```ruby # config/initializers/doorkeeper.rb Doorkeeper::ClientAuthentication.register( :partner_headers, PartnerHeaders::Authentication, ) Doorkeeper.configure do client_authentication %i[client_secret_basic client_secret_post partner_headers none] # ... end ``` -------------------------------- ### Test Token Refresh - Success Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem Demonstrates testing the refresh token functionality. It acquires an initial token, simulates time passing to expire it, and then refreshes it. ```ruby require 'acceptance/acceptance_helper' feature 'OAuth authorization' do let(:app) { create(:application) } let(:user) { create(:user) } scenario 'refresh ok' do client = OAuth2::Client.new(app.uid, app.secret) do |b| b.request :url_encoded b.adapter :rack, Rails.application end token = client.password.get_token(user.email, user.password) token.should_not be_expired Timecop.freeze(Time.now + 1.day) do expect(token).to be_expired token2 = token.refresh! expect(token2).not_to be_expired end end end ``` -------------------------------- ### Run Tests with Docker Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/CONTRIBUTING.md Execute the tests within the Docker container. ```docker docker run -it --rm doorkeeper:test ``` -------------------------------- ### Generate Migration for Confidential Applications Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Use this command to generate a migration file for adding the 'confidential' column to the Doorkeeper::Application table. This column is crucial for supporting Public & Private Clients. ```bash rails generate doorkeeper:confidential_applications ``` -------------------------------- ### PostgreSQL Schema After Applying MD5 Index Solution Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/How-to-fix-PostgreSQL-error-on-index-row-size This output shows the updated schema of the 'oauth_access_tokens' table after the MD5 hash index has been applied. Note the new index definition for 'index_oauth_access_tokens_on_refresh_token'. ```sql identity-provider_development=# \d oauth_access_tokens Table "public.oauth_access_tokens" Column | Type | Modifiers -------------------+-----------------------------+------------------------------------------------------------------ id | integer | not null default nextval('oauth_access_tokens_id_seq'::regclass) resource_owner_id | integer | application_id | integer | token | character varying | not null refresh_token | character varying | expires_in | integer | revoked_at | timestamp without time zone | created_at | timestamp without time zone | not null scopes | character varying | Indexes: "oauth_access_tokens_pkey" PRIMARY KEY, btree (id) "index_oauth_access_tokens_on_token" UNIQUE, btree (token) "index_oauth_access_tokens_on_refresh_token" btree (md5(refresh_token::text)) "index_oauth_access_tokens_on_resource_owner_id" btree (resource_owner_id) ``` -------------------------------- ### Generate Doorkeeper Views Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-views Use this command to copy Doorkeeper's default views into your application's `app/views/doorkeeper` directory. Doorkeeper will prioritize these views over its defaults. ```bash rails generate doorkeeper:views ``` -------------------------------- ### Access Current User via Environment Variable (Clearance) Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Authenticating-using-Clearance-or-DIY Use this snippet in `config/initializers/doorkeeper.rb` to access the authenticated user through the `env` variable when using Clearance >= 0.13.0. It redirects to the sign-in page if no user is found. ```ruby resource_owner_authenticator do @user = env[:clearance].current_user unless @user session[:return_to] = request.fullpath redirect_to(sign_in_url) end @user end ``` -------------------------------- ### Format multiple resource indicators Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Use Rails bracket syntax for multiple resource indicators to ensure they are correctly parsed by Rack. ```text ?resource[]=https://api.example.com/&resource[]=https://calendar.example.com/ ``` -------------------------------- ### Enable PostgreSQL UUID Extension Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-PostgreSQL-UUIDs-as-primary-keys-with-Doorkeeper Generate a migration to enable the 'pgcrypto' extension in PostgreSQL, which is necessary for using UUIDs. ```ruby class EnableUuidExtension < ActiveRecord::Migration def change enable_extension 'pgcrypto' end end ``` -------------------------------- ### Request First Access Token Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Enable-Refresh-Token-Credentials After the user authorizes the client, use the obtained authorization code to request the initial access token and refresh token from the provider. ```ruby token = client.auth_code.get_token(code, :redirect_uri => redirect_uri) # POST '/oauth/token' with grant_type set to authorization_code # => # ``` -------------------------------- ### Mock Redis Connection for Testing Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Rate-limit-with-Redis To test your Rack application with rate limiting, mock the Redis connection by requiring the testing connection file provided by the gem. ```ruby # Rate limit fake redis connection require 'rack/redis_throttle/testing/connection' ``` -------------------------------- ### Register a Custom Client Authentication Strategy Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions Register a new custom authentication strategy with Doorkeeper. Ensure the custom strategy implements the required `matches_request?` and `authenticate` methods. ```ruby Doorkeeper::ClientAuthentication.register(:my_method, MyStrategy) ``` -------------------------------- ### Server Output for Password Grant Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This snippet shows the server logs when a password grant is processed by Doorkeeper. ```log Started POST "/oauth/token" for 127.0.0.1 at 2014-02-26 17:56:17 -0500 Processing by Doorkeeper::TokensController#create as */* Parameters: {"grant_type"=>"password", "username"=>"user@example.com", "password"=>"[FILTERED]"} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'user@example.com' LIMIT 1 (0.2ms) SELECT 1 FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = '0ddb922452c983a70566e30dce16e2017db335103e35d783874c448862a78168' LIMIT 1 (0.1ms) SELECT 1 FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."refresh_token" = 'f2188c4165d912524e04c6496d10f06803cc08ed50271a0b0a73061e3ac1c06c' LIMIT 1 SQL (0.6ms) INSERT INTO "oauth_access_tokens" ("application_id", "created_at", "expires_in", "refresh_token", "resource_owner_id", "revoked_at", "scopes", "token") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["application_id", nil], ["created_at", Wed, 26 Feb 2014 22:56:17 UTC +00:00], ["expires_in", 7200], ["refresh_token", "f2188c4165d912524e04c6496d10f06803cc08ed50271a0b0a73061e3ac1c06c"], ["resource_owner_id", 1], ["revoked_at", nil], ["scopes", "public"], ["token", "0ddb922452c983a70566e30dce16e2017db335103e35d783874c448862a78168"]] Completed 200 OK in 106ms ``` -------------------------------- ### Require New Relic Instrumentation File Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/NewRelic-support-for-Doorkeeper::TokensController Include the custom New Relic instrumentation file in your Doorkeeper initializer configuration. ```ruby require_relative '../../lib/doorkeeper/newrelic' ``` -------------------------------- ### Define a Grant Strategy Class Source: https://github.com/doorkeeper-gem/doorkeeper/blob/main/README.md Create a strategy class that inherits from Doorkeeper::Request::Strategy to process the token request. ```ruby module SamlBearer class Strategy < Doorkeeper::Request::Strategy delegate :client, :parameters, to: :server def request @request ||= TokenRequest.new(Doorkeeper.config, client, parameters) end end end ``` -------------------------------- ### Define Doorkeeper Routes in an API Engine Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/Integration-with-multi-engine-Rails-application Use `use_doorkeeper` in the main application's routes to set up Doorkeeper, and then define the API engine's routes separately. This ensures Doorkeeper endpoints are correctly mounted. ```ruby Rails.application.routes.draw do use_doorkeeper scope: 'api/v1/oauth' end Api::Engine.routes.draw do scope 'v1' do # your other engine routes here end end ``` -------------------------------- ### Command Output for Deleting Authorized Application Source: https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples This shows the expected output after successfully revoking an API client authorization. ```text redirect to /oauth/authorized_applications ```