I am trying to implement Omniauth with Devise in Rails API with NuxtJS framework.
I did auth module connexion and user account creation with Omniauth method but i would like understand how redirect the user afer signin/signup, i am Rails developer and beginner with NuxtJS.
BACKEND
User model oauth registration method:
def self.from_facebook(auth)
where(uid: auth.uid, provider: auth.provider).first_or_create do |user|
user.email = auth.info.email
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.password = Devise.friendly_token[0, 20]
user.provider = auth.provider
user.uid = auth.uid
Client.create(user: user)
end
end
Registration controller:
# frozen_string_literal: true
module Overrides
class RegistrationsController < DeviseTokenAuth::ApplicationController
before_action :set_user_by_token, only: [:destroy, :update]
before_action :validate_sign_up_params, only: :create
before_action :validate_account_update_params, only: :update
skip_after_action :update_auth_header, only: [:create, :destroy]
def create
build_resource
unless @resource.present?
raise DeviseTokenAuth::Errors::NoResourceDefinedError,
"#{self.class.name} #build_resource does not define @resource,"\
' execution stopped.'
end
# give redirect value from params priority
@redirect_url = params.fetch(
:confirm_success_url,
DeviseTokenAuth.default_confirm_success_url
)
# success redirect url is required
if confirmable_enabled? && !@redirect_url
return render_create_error_missing_confirm_success_url
end
# if whitelist is set, validate redirect_url against whitelist
return render_create_error_redirect_url_not_allowed if blacklisted_redirect_url?
# override email confirmation, must be sent manually from ctrl
resource_class.set_callback('create', :after, :send_on_create_confirmation_instructions)
resource_class.skip_callback('create', :after, :send_on_create_confirmation_instructions)
if @resource.respond_to? :skip_confirmation_notification!
# Fix duplicate e-mails by disabling Devise confirmation e-mail
@resource.skip_confirmation_notification!
end
if @resource.save
if params[:farmer]
Farmer.create(
user: @resource
)
else
Client.create(
user: @resource
)
end
yield @resource if block_given?
unless @resource.confirmed?
# user will require email authentication
@resource.send_confirmation_instructions({
client_config: params[:config_name],
redirect_url: @redirect_url
})
end
if active_for_authentication?
# email auth has been bypassed, authenticate user
@client_id, @token = @resource.create_token
@resource.save!
update_auth_header
end
render_create_success
else
clean_up_passwords @resource
render_create_error
end
end
def update
if @resource
if @resource.send(resource_update_method, account_update_params)
yield @resource if block_given?
render_update_success
else
render_update_error
end
else
render_update_error_user_not_found
end
end
def destroy
if @resource
@resource.destroy
yield @resource if block_given?
render_destroy_success
else
render_destroy_error
end
end
def sign_up_params
params.permit(
:first_name,
:last_name,
:email,
:cellphone,
:phone,
:password,
:password_confirmation,
:birthdate
)
end
def account_update_params
params.permit(*params_for_resource(:account_update))
end
protected
def build_resource
@resource = resource_class.new(sign_up_params)
@resource.provider = provider
# honor devise configuration for case_insensitive_keys
if resource_class.case_insensitive_keys.include?(:email)
@resource.email = sign_up_params[:email].try(:downcase)
else
@resource.email = sign_up_params[:email]
end
end
def render_create_error_missing_confirm_success_url
response = {
status: 'error',
data: resource_data
}
message = I18n.t('devise_token_auth.registrations.missing_confirm_success_url')
render_error(422, message, response)
end
def render_create_error_redirect_url_not_allowed
response = {
status: 'error',
data: resource_data
}
message = I18n.t('devise_token_auth.registrations.redirect_url_not_allowed', redirect_url: @redirect_url)
render_error(422, message, response)
end
def render_create_success
render json: {
status: 'success',
data: resource_data
}
end
def render_create_error
render json: {
status: 'error',
data: resource_data,
errors: resource_errors
}, status: 422
end
def render_update_success
render json: {
status: 'success',
data: resource_data
}
end
def render_update_error
render json: {
status: 'error',
errors: resource_errors
}, status: 422
end
def render_update_error_user_not_found
render_error(404, I18n.t('devise_token_auth.registrations.user_not_found'), status: 'error')
end
def render_destroy_success
render json: {
status: 'success',
message: I18n.t('devise_token_auth.registrations.account_with_uid_destroyed', uid: @resource.uid)
}
end
def render_destroy_error
render_error(404, I18n.t('devise_token_auth.registrations.account_to_destroy_not_found'), status: 'error')
end
private
def resource_update_method
if DeviseTokenAuth.check_current_password_before_update == :attributes
'update_with_password'
elsif DeviseTokenAuth.check_current_password_before_update == :password && account_update_params.key?(:password)
'update_with_password'
elsif account_update_params.key?(:current_password)
'update_with_password'
else
'update_attributes'
end
end
def validate_sign_up_params
validate_post_data sign_up_params, I18n.t('errors.messages.validate_sign_up_params')
end
def validate_account_update_params
validate_post_data account_update_params, I18n.t('errors.messages.validate_account_update_params')
end
def validate_post_data which, message
render_error(:unprocessable_entity, message, status: 'error') if which.empty?
end
def active_for_authentication?
!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?
end
end
end
Omniauth callbacks controller:
def facebook
@user = User.from_facebook(request.env["omniauth.auth"])
# NOTE: redirection here
end
FRONTEND
Stategie:
facebook: {
client_id: 'CLIENT_ID',
userinfo_endpoint: 'https://graph.facebook.com/v2.12/me?fields=about,name,picture{url},email,birthday',
redirect_uri:'http://localhost:3000/omniauth/facebook',
scope: ['public_profile', 'email', 'user_birthday']
}
Login method:
facebookLogin () {
this.$auth.loginWith('facebook')
.then((response) => {
this.$toast.success({
title: 'Connexion réussie',
message: 'Vous vous êtes bien connecté.',
position: 'bottom center',
timeOut: 3000
})
})
.catch(() => {
this.$toast.error({
title: 'Erreur',
message: 'L\'email ou le mot de passe ne sont pas valides. Vérifiez votre saisie.',
position: 'bottom center',
timeOut: 8000
})
})
.finally(() => this.$wait.end('signing in'))
}
A couple of things...
sign_in_and_redirect @user
underneath the @user = ...
line.devise for :users
in your routes.rb file. Check out the "Devise_for magic" section on this page to see an example of these built in routes. Note that you have to have some Devise models configured for this to work.rake routes
to see if the routes you have defined are what you're expecting.