【问题标题】:How can I set the authentications table when using Omniauth Identity?使用 Omniauth Identity 时如何设置身份验证表?
【发布时间】:2023-04-05 14:55:02
【问题描述】:

我正在尝试将 Omniauth Identity 添加到我的 Rails 应用程序。这样我最终可以支持本地和 OAuth 登录。

我一直在使用以下 Gist 获取有关如何使其正常工作的信息 - https://gist.github.com/stefanobernardi/3769177

问题是当一个新用户在数据库的用户表中注册时,authentications 表没有填充 user_id 或提供程序。这意味着登录失败,因为系统无法使用provider 从数据库中获取正确的用户。

models/authentication.rb

class Authentication < ApplicationRecord

  attr_accessor :provider, :uid, :user_id
  belongs_to :user


  def self.find_with_omniauth(auth)
    find_by_provider_and_uid(auth['provider'], auth['uid'])
  end

  def self.create_with_omniauth(auth)
    create(uid: auth['uid'], provider: auth['provider']) # and other data you might want from the auth hash
  end

end

controller/sessions_controller.rb

class SessionsController < ApplicationController

  skip_before_action :verify_authenticity_token, only: :create

  def new
  end


  def create_old
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      redirect_back_or user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end


  def create

    auth = request.env['omniauth.auth']

    # Find an authentication or create one
    if @authentication.nil?

      # If no authentication was found, create new one here
      @authentication = Authentication.create_with_omniauth(auth)

    end

    if logged_in?

      if @authentication.user == current_user

        # User is signed in so they are trying to link an authentication with their
        # account.  But an authentication has been found and the user associated with it
        # is the current user.  So the authentication is already associated with the 
        # this user, therefore display an error
        redirect_to root_path, notice: "You have already linked this account"
      else

        # The authentication is not associated with the current_user to associate
        # the authentication
        @authentication.user = current_user
        @authentication.save
        redirect_to root_path, notice: "Account successfully authenticated"
      end
    else # no user is signed in

      if @authentication.user.present?

        # The authentication that has been found had a user associated with it so 
        # just lof them in 
        self.current_user = @authentication.user
        redirect_to root_path, notice: "Signed in"
      else

        # The authentication has no user assigned and there is not user signed in
        # The decision here is to create a new account for the user
        # Check for the Omniauth Idenitity provider which is local auth
        if @authentication.provider == 'identity'

          u = User.find(@authentication.uid)

          # if using the identity provior then the user is local so just find
          # in the database
        else

          # Create a new user in the databse using the hash of information from the 
          # omniauth
          u = User.create_with_omniauth(auth)
        end

        # Now can link the authentication with the user
        u.authentications << @authentication
        self.current_user = u
        redirect_to root_path, notice: "Welcome"
      end

    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end

  def failure
    redirect_to root_path, alert: "Authentication failed, please try again"
  end
end

数据库的架构是

ActiveRecord::Schema.define(version: 20170426182907) do

  create_table "authentications", force: :cascade do |t|
    t.integer  "user_id"
    t.string   "provider"
    t.string   "uid"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_authentications_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
    t.string   "password_digest"
    t.string   "remember_digest"
    t.index ["email"], name: "index_users_on_email", unique: true
  end

end

在用户表中创建用户没有问题,authentication 对象确实包含提供者信息,它只是没有进入身份验证表。创建了一条记录,但不是与提供者一起创建的。

很乐意提供更多信息,但不想让帖子太长(可能)包含不相关的信息。我敢肯定,我错过了一些非常简单的事情,只是没有正确地将事物连接在一起。

【问题讨论】:

    标签: ruby-on-rails authentication omniauth


    【解决方案1】:

    这是由models/authentication.rb 文件中的以下行引起的

       attr_accessor :uid, :provider, :user_id
    

    通过此设置,provider 未在数据库中设置。从此列表中删除它会将数据保留在数据库中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多