我正在尝试将Omniauth Identity添加到我的Rails应用程序中。这样我最终可以支持本地和OAuth登录。
我一直在使用以下要点获取有关如何使其发挥作用的信息 - https://gist.github.com/stefanobernardi/3769177。
问题是,当在数据库的Users表中注册新用户时,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
用户在Users表中创建没有问题,authentication
对象容纳了提供者信息,它只是没有进入身份验证表。创建记录,而不是提供者。
很高兴提供更多信息,但不希望使用(可能)无关信息使帖子过长。我确信这是一件非常简单的事情,我错过了,而且没有正确地将事物连接在一起。
答案 0 :(得分:0)
这是由models/authentication.rb
文件
attr_accessor :uid, :provider, :user_id
通过设置此设置,数据库中未设置provider
。从此列表中删除它会将数据保留在数据库中。