我正在开发一个使用 Discord OAuth 作为身份验证方法的应用程序。因为这个应用程序需要一个 Discord 帐户,所以我只使用 omniauth-discord,而不是任何本地身份验证方法。 但是在 Discord 回调后的身份验证期间,我丢失了会话。用户将在MongoDB中创建,但之后,current_user将返回一个nil
值。
我可以毫无问题地调用 Discord OAuth,并从回调中获取信息,存储在 MongoDB 中,但比我尝试授权用户使用该站点,没有可用的会话,因此 logininfo 每次都会返回 401。如果我尝试再次登录,我总是会收到 Discord 同意页面。 我已经从教程中尝试了许多不同的代码,但其中大多数使用 Devise 进行本地登录和身份验证,然后将本地用户与 Discord 连接。 还尝试在代码的不同部分初始化会话,但没有任何运气。
我已经为代码的当前情况创建了一个 github 存储库。你可以在这里找到它: https://github.com/montyx99/ppapi
我的sessions_contoller.rb:
require 'json'
class SessionsController < ApplicationController
def new
redirect_to '/auth/discord'
end
def current_user
super
end
def create
session[:init] = true
auth = request.env["omniauth.auth"]
user = User.where(:discord_id => auth.extra.raw_info.id).first || User.create_with_omniauth(auth)
p user
p user.discord_id
# Reset the session after successful login, per
# 2.8 Session Fixation – Countermeasures:
# http://guides.rubyonrails.org/security.html#session-fixation-countermeasures
reset_session
session[:user_id] = user.discord_id
p session[:user_id]
redirect_to "http://localhost:3000", :notice => 'Signed in!'
end
def destroy
reset_session
redirect_to "http://localhost:3000", :notice => 'Signed out!'
end
def failure
redirect_to "http://localhost:3000", :alert => "Authentication error: #{params[:message].humanize}"
end
def logininfo
p current_user
if current_user
render :json => true, :status => 200
else
render :json => false, :status => 401
end
end
end
application_controller.rb
class ApplicationController < ActionController::API
def current_user
begin
@current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue Exception => e
nil
end
end
def user_signed_in?
return true if current_user
end
def correct_user?
@user = User.find(params[:id])
unless current_user == @user
redirect_to root_url, :alert => "Access denied."
end
end
def authenticate_user!
if !current_user
redirect_to root_url, :alert => 'You need to sign in for access to this page.'
end
end
def logging
id = ENV["DISCORD_CLIENT_ID"]
secret = ENV["DISCORD_CLIENT_SECRET"]
end
end
预期:
与 Discord第一次握手后,用户需要能够在没有 Discord 同意页面的情况下再次登录
首先,您将discord_id分配为session[:user_id]
中的用户 ID。然后,当您在current_user
中调用User.find
时,您不会搜索您的discord_id用户属性,默认情况下,find 将按 user.id 搜索。您的实际 user.id 可能是数据库分配的整数。
你的开始在current_user也是多余的。取出它,第一端缩进。从方法的开头开始是隐含的,所以你只需要在结束之前进行救援。