Rails API Omniauth

问题描述

我正在尝试通过NuxtJS框架在Rails API中使用Devise实现Omniauth。

我使用Omniauth方法进行了身份验证模块的连接和用户帐户的创建,但是我想了解如何在登录/注册后重定向用户,我是Rails开发人员,也是NuxtJS的初学者。

后退

用户模型oauth注册方法:

func windowMode() -> String {
  let screenRect = UIScreen.main.bounds
  let appRect = UIApplication.shared.windows[0].bounds

  if (UIDevice.current.userInterfaceIdiom == .phone) {
    return "iPhone fullscreen"
  } else if (screenRect == appRect) {
    return "iPad fullscreen"
  } else if (appRect.size.height < screenRect.size.height) {
    return "iPad slide over"
  } else {
    return "iPad split view"
  }
}

注册控制器:

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

Omniauth回调控制器:

# 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',: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,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',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,status: 'error') if which.empty?
end

def active_for_authentication?
  !@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?
end
end
end

状态:

def facebook
@user = User.from_facebook(request.env["omniauth.auth"])

# NOTE: redirection here
end

登录方法:

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']
  }

解决方法

几件事...

  1. Omniauth回调控制器缺少重定向信息(这就是为什么存在该注释的原因?)。如果您使用的是Devise,它应该在sign_in_and_redirect @user行下方显示@user = ...之类的字眼。
  2. Devise带有内置路线。要使用它们,必须在routes.rb文件中包含devise for :users之类的东西。请查看this page上的“ Devise_for魔术”部分,以查看这些内置路线的示例。请注意,您必须配置一些Devise模型才能使其正常工作。
  3. 运行rake routes来查看您定义的路由是否符合您的期望。
  4. 如果您无法弄清楚,我还使用Omniauth创建了一个项目并进行设计。您可以查看我的代码here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...