# Terminal
rails _5.2.2_ new api_demo --api
rails g devise_token_auth:install User auth
# Gemfile
gem 'devise_token_auth'
gem 'omniauth-github'
gem 'omniauth-google-oauth2'
gem 'rack-cors', require: 'rack/cors'
# routes.rb
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
omniauth_callbacks: 'devise_token_auth/custom_omniauth_callbacks'
}
# models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
include DeviseTokenAuth::Concerns::User
end
# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: 'email,profile'
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET']
end
# config/application.rb
config.middleware.insert_after ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies
config.middleware.insert_after ActionDispatch::Cookies, ActionDispatch::Session::CookieStore
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
# allow do
# origins 'example.com'
# resource '*',
# headers: :any,
# methods: [:get, :post, :put, :patch, :delete, :options, :head]
# end
allow do
origins '*'
resource '*',
headers: :any,
expose: ['access-token', 'expiry', 'token-type', 'uid', 'client'],
methods: [:get, :post, :options, :delete, :put]
end
end
# application_controller.rb
class ApplicationController < ActionController::API
include DeviseTokenAuth::Concerns::SetUserByToken
end
# controllers/devise_token_auth/custom_omniauth_callbacks_controller.rb
module DeviseTokenAuth
class CustomOmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
protected
def render_data_or_redirect(message, data, user_data = {})
if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type) || auth_origin_url
redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data.merge(blank: true))
else
fallback_render data[:error] || 'An error occurred'
end
end
end
end
# j-toker configuration
Auth.configure([
{
default: {
apiUrl: 'https://your-domain-name',
proxyIf: function() { return window.isOldIE(); },
signOutUrl: '/auth/sign_out',
emailSignInPath: '/auth/sign_in',
emailRegistrationPath: '/auth',
accountUpdatePath: '/auth',
accountDeletePath: '/auth',
passwordResetPath: '/auth/password',
passwordUpdatePath: '/auth/password',
tokenValidationPath: '/auth/validate_token',
authProviderPaths: {
github: '/auth/github',
facebook: '/auth/facebook',
google: '/auth/google_oauth2'
}
}
}
]);