Last active
April 30, 2021 12:23
-
-
Save jigneshkhokhani/7432669d1d161fd70658b2efe21df4ec to your computer and use it in GitHub Desktop.
medium-(Rails API + Doorkeeper + Devise)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::API | |
# Devise code | |
before_action :configure_permitted_parameters, if: :devise_controller? | |
# Doorkeeper code | |
before_action :doorkeeper_authorize! | |
respond_to :json | |
protected | |
# Devise methods | |
# Authentication key(:username) and password field will be added automatically by devise. | |
def configure_permitted_parameters | |
added_attrs = [:email, :first_name, :last_name] | |
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs | |
devise_parameter_sanitizer.permit :account_update, keys: added_attrs | |
end | |
private | |
# Doorkeeper methods | |
def current_resource_owner | |
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CustomTokenErrorResponse | |
def body | |
{ | |
status_code: 401, | |
message: I18n.t('devise.failure.invalid', authentication_keys: User.authentication_keys.join('/')), | |
result: [] | |
} | |
# or merge with existing values by | |
# super.merge({key: value}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CustomTokenResponse | |
def body | |
user_details = User.find(@token.resource_owner_id) | |
# call original `#body` method and merge its result with the additional data hash | |
super.merge({ | |
status_code: 200, | |
message: I18n.t('devise.sessions.signed_in'), | |
result: user_details | |
}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Doorkeeper.configure do | |
# Change the ORM that doorkeeper will use (needs plugins) | |
orm :active_record | |
# This block will be called to check whether the resource owner is authenticated or not. | |
resource_owner_authenticator do | |
fail "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}" | |
# Put your resource owner authentication logic here. | |
# Example implementation: | |
# User.find_by_id(session[:user_id]) || redirect_to(new_user_session_url) | |
end | |
# In this flow, a token is requested in exchange for the resource owner credentials (username and password) | |
resource_owner_from_credentials do |routes| | |
user = User.find_for_database_authentication(:username => params[:username]) | |
if user && user.valid_for_authentication? { user.valid_password?(params[:password]) } | |
user | |
end | |
end | |
... | |
# Access token expiration time (default 2 hours). | |
# If you want to disable expiration, set this to nil. | |
access_token_expires_in 5.days | |
... | |
# | |
# implicit and password grant flows have risks that you should understand | |
# before enabling: | |
# http://tools.ietf.org/html/rfc6819#section-4.4.2 | |
# http://tools.ietf.org/html/rfc6819#section-4.4.3 | |
# | |
# grant_flows %w(authorization_code client_credentials) | |
grant_flows %w(password) | |
# Under some circumstances you might want to have applications auto-approved, | |
# so that the user skips the authorization step. | |
# For example if dealing with a trusted application. | |
# skip_authorization do |resource_owner, client| | |
# client.superapp? or resource_owner.admin? | |
# end | |
skip_authorization do | |
true | |
end | |
# WWW-Authenticate Realm (default "Doorkeeper"). | |
# realm "Doorkeeper" | |
end | |
Doorkeeper::OAuth::TokenResponse.send :prepend, CustomTokenResponse | |
Doorkeeper::OAuth::ErrorResponse.send :prepend, CustomTokenErrorResponse |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cancel_user_registration GET /api/users/cancel(.:format) api/v1/users/registrations#cancel {:format=>:json} | |
new_user_registration GET /api/users/sign_up(.:format) api/v1/users/registrations#new {:format=>:json} | |
edit_user_registration GET /api/users/edit(.:format) api/v1/users/registrations#edit {:format=>:json} | |
user_registration PATCH /api/users(.:format) api/v1/users/registrations#update {:format=>:json} | |
PUT /api/users(.:format) api/v1/users/registrations#update {:format=>:json} | |
DELETE /api/users(.:format) api/v1/users/registrations#destroy {:format=>:json} | |
POST /api/users(.:format) api/v1/users/registrations#create {:format=>:json} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Api::V1::Users::RegistrationsController < Devise::RegistrationsController | |
# before_action :configure_sign_up_params, only: [:create] | |
# before_action :configure_account_update_params, only: [:update] | |
# Somehow respond_to is not working so I manually render as json | |
skip_before_action :doorkeeper_authorize! | |
# respond_to :json | |
# GET /resource/sign_up | |
# def new | |
# super | |
# end | |
# POST /resource | |
def create | |
build_resource(sign_up_params) | |
resource.save | |
if resource.persisted? | |
if resource.active_for_authentication? | |
# set_flash_message! :notice, :signed_up | |
# To avoid login comment out sign_up method | |
# sign_up(resource_name, resource) | |
render json: resource # , location: after_sign_up_path_for(resource) | |
else | |
# set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}" | |
expire_data_after_sign_in! | |
render json: resource # , location: after_inactive_sign_up_path_for(resource) | |
end | |
else | |
clean_up_passwords resource | |
set_minimum_password_length | |
respond_with resource | |
end | |
end | |
# GET /resource/edit | |
# def edit | |
# super | |
# end | |
# PUT /resource | |
# def update | |
# super | |
# end | |
# DELETE /resource | |
# def destroy | |
# super | |
# end | |
# GET /resource/cancel | |
# Forces the session data which is usually expired after sign | |
# in to be expired now. This is useful if the user wants to | |
# cancel oauth signing in/up in the middle of the process, | |
# removing all OAuth session data. | |
# def cancel | |
# super | |
# end | |
protected | |
# Overwrite : Devise method | |
# Signs in a user on sign up. | |
# def sign_up(resource_name, resource) | |
# # Do not sign in user after successfull registration | |
# # sign_in(resource_name, resource) | |
# end | |
# If you have extra params to permit, append them to the sanitizer. | |
# def configure_sign_up_params | |
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attributes]) | |
# end | |
# If you have extra params to permit, append them to the sanitizer. | |
# def configure_account_update_params | |
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) | |
# end | |
# The path used after sign up. | |
# def after_sign_up_path_for(resource) | |
# super(resource) | |
# end | |
# The path used after sign up for inactive accounts. | |
# def after_inactive_sign_up_path_for(resource) | |
# super(resource) | |
# end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rails.application.routes.draw do | |
# Use for login and autorize all resource | |
use_doorkeeper do | |
# No need to register client application | |
skip_controllers :applications, :authorized_applications | |
end | |
scope module: :api, defaults: { format: :json }, path: 'api' do | |
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do | |
devise_for :users, controllers: { | |
registrations: 'api/v1/users/registrations', | |
}, skip: [:sessions, :password] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how we have do for sessions controller i.e sign in/login process ?