I'm using devise_token_auth for Email and Google Oauth2 based authentication(used omniauth-google-oauth2
gem for this). I've successfully managed to store sign in info of the user signing up/in through Google Oauth2 flow. The info includes:
{"auth_token"=>"token here", "client_id"=>"client id here", "uid"=>"uid here", "expiry"=>1620492005, "config"=>nil, "oauth_registration"=>true}
The flow for the above info was
The code which executes for the first step is
module DeviseTokenAuth
class OmniauthCallbacksController < DeviseTokenAuth::ApplicationController
attr_reader :auth_params
before_action :validate_auth_origin_url_param
def omniauth_success
get_resource_from_auth_hash
set_token_on_resource
create_auth_params
if confirmable_enabled?
# don't send confirmation email!!!
@resource.skip_confirmation!
end
sign_in(:user, @resource, store: false, bypass: false)
@resource.save!
yield @resource if block_given?
render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)
end
end
end
Problems I'm facing:
sign_in
method call does not set @current_user
despite that @resource
and @auth_params
have all the necessary info in them.render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)
this call does not redirect or render anything, instead it stays on the same page the URL it shows is http://localhost:3000/auth/google_oauth2/callback#
I basically have three questions now:
devise_token_auth
to set the current_user
based on the incoming auth headers?
I have added the following line to my controller, but still it fails to set @current_user
include DeviseTokenAuth::Concerns::SetUserByToken
maybe it is because I'm sending auth headers incorrectly? See my 3rd point below for this.
How am I supposed to send the sign in info to my frontend app? Do I modify the above method somehow to send sign in info to my frontend app?
What and where do I put the auth headers in order to make authenticated requests?
devise_token_auth
with email as auth provider I have to send 3 pieces to make an authenticated request i.e access-token
, client_id
and uid
I have used postman to test both of the following but it failed with Unauthorized error
access-token
, client_id
and uid
in headersBearer my_token
in authorization headers.To get this working, we had to override the DeviseTokenAuth
's OmniAuthCallbacks
controller and update its render_data_or_redirect
method.
The default definition of render_data_or_redirect
is
def render_data_or_redirect(message, data, user_data = {})
if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
render_data(message, user_data.merge(data))
elsif 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
The following routes.rb
and custom_omniauth_callbacks_controller.rb
have the changes needed to be done to get it working with j-toker
library.
In the routes file
# config/routes.rb
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
omniauth_callbacks: "devise_token_auth/custom_omniauth_callbacks"
}
and the definition of CustomOmniAuthCallbacksController
was
# app/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
now on the front-end side you need to configure j-toker
First, install j-toker package, yarn package or npm package
yarn add j-toker
or
npm i j-toker
then in your javascript application, configure the j-toker
import $ from "jquery";
$.auth.configure({
apiUrl: "https://your-api-domain.com",
emailSignInPath: "/auth/sign_in",
signOutPath: "/auth/sign_out",
emailRegistrationPath: "/auth",
tokenValidationPath: "/auth/validate_token"
authProviderPaths: {
facebook: "/auth/facebook",
google: "/auth/google_oauth2"
}
});