私はRailsアプリケーションにOmniauth Identityを追加しようとしています。これは、ローカルとOAuthのログインを最終的にサポートできるようにするためです。Omniauth IDを使用するときに認証テーブルを設定するにはどうすればよいですか?
私はこの作業を行う方法について、以下のGistを使用しています。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
オブジェクトがコンテナんですプロバイダ情報認証テーブルには向かない。レコードが作成されますが、プロバイダとは関係ありません。
さらに詳しい情報を提供しても大丈夫ですが、あまりにも長い(あまりにも)無関係な情報で投稿を長くしたくないです。私はそれが私が行方不明であり、物事を適切に結びつけていないということは非常に簡単なものだと確信しています。