我决定自定义(覆盖)Devise的会话控制器来实现我自己的登录逻辑。我已经离开会议#new控制器而只是简单地调用super。
def new
super
end
但是,我已经在我的自定义会话#create方法中删除了对super的调用,以便我可以向服务器发送HTTP请求以进行身份验证。随后,我要么登录用户,要么将用户返回到会话#new路径再次尝试登录。
def create
@member = Member.find_by_username(params[:username])
response = authenticate_with_api
if response[:authenticated]
if @member
@member.update(response.[:member])
sign_in @member
else
@member.create(response.[:member])
sign_in @member
end
else
flash[:alert] = "Incorrect username or password"
flash[:error] = "Incorrect username or password"
flash[:notice] = "Incorrect username or password" #setting all the messages out of frustration!
redirect_to new_member_session_path
end
逻辑流程正常工作,但不显示flash消息。我在新方法中调用super之前设置了一条flash消息,以确保视图设置正确:
def new
flash[:notice] = "Test flash message"
super
end
这很有效。我可以看到模板中出现了flash消息。我能想到的唯一解释是,不知何故,有多个重定向发生。但是,当我查看日志时,我只能看到我指定的重定向。我也尝试使用keep来通过多个请求持久保存flash消息,但即使这样也行不通:
flash.keep[:notice] = "Test flash message"
redirect_to new_member_session_path #does not work
我也尝试使用现在作为最后的努力:
flash.now[:notice] = "Test flash message"
没有骰子。最后,我尝试将flash消息与重定向内联:
redirect_to new_member_session_path, flash: { :notice => "Test flash message" } #also does not work
我不知所措。不确定闪存消息丢失的原因。我正在运行Rails 4.1.2和Devise 3.2.4
编辑:
我认为这不是自定义身份验证的最佳方式。相反,我已经创建了一个自定义的Warden策略,并告诉它:
#config/initializers/devise.rb
config.warden do |manager|
manager.intercept_401 = false
manager.default_strategies(:scope => :member).unshift :member_login
end
我将所有逻辑放在该文件中:
Warden::Strategies.add(:member_login) do
def member_params
ActionController::Parameters.new(@response).permit(:first_name, :last_name, :role, :username, :parkplace_user_id)
end
def valid?
params[:member] && ( params[:member][:username] || params[:member][:password] )
end
def authenticate!
member = Member.find_by_username(params[:member][:username])
if authenticate_with_ppd_api
if member
member.update(member_params)
success!(member)
else
member = Member.create(member_params)
success!(member)
end
else
fail!("Incorrect username or password")
end
end
def authenticate_with_api
@response = HTTParty.post('https://path.to.server/admin/login', body: { username: params[:member][:username], password: params[:member][:password] } )
@response = JSON.parse(@response.body).first
@response["authenticated"]
end
end
Flash消息现在正在出现,但我在登录时遇到了其他问题。我为此创建了一个新问题。谢谢!