【发布时间】: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