Rails 4:通过设计,我如何基于user_id对用户进行身份验证

时间:2014-12-15 03:47:15

标签: ruby-on-rails-4 cookies devise

我有两类用户,即提供电子邮件地址和可选密码的用户,以及(甚至更多)仅提供其姓名的轻量级用户。当轻量级用户返回我的网站时 - 关闭浏览器后 - 他们的名字应该自动记住,并且应该使用他们的轻量级权限自动登录。鉴于该名称可能不是唯一的,我想根据用户ID对轻量级用户进行签名。

(轻量级用户可以稍后通过添加电子邮件地址成为完整用户。)

我正在使用Devise,我的user.rb文件包含:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  def password_required?
    false
  end

  def email_required?
    false
  end

  def remember_me
    true
  end

在devise.rb初始化程序中,我尝试设置

config.authentication_keys = [ :user_id ]

但除了破坏具有电子邮件地址的用户的身份验证之外,它没有任何效果。

使用config.authentication_keys = [:email],即使浏览器重新启动/会话cookie被销毁,提交电子邮件地址的返回用户也会在返回时成功登录到站点。但是,重新启动浏览器时会忘记仅返回名称的用户。在这两种情况下都存在remember_user_token cookie。

查看https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address,我可能需要覆盖Devise的find_for_database_authentication方法,但我不确定要放入什么或者是否足够;我已经尝试了一些变化而没有成功。

1 个答案:

答案 0 :(得分:0)

终于弄明白了;这是其他人有同样问题的答案。

相关登录过程发生在Devise的Rememberable模块中。

Devise在remember_user_token cookie中的会话之间存储已保存的用户信息。 Cookie包含用户ID和记忆令牌。

如果电子邮件和密码都为空,则记住令牌也将为空,导致内部设计比较(secure_compare)失败。这将导致会话丢失并且remember_user_token cookie将被销毁。

要解决此问题,您可以为没有用户的用户设置临时密码。一种方法如下。

class RegistrationsController < Devise::RegistrationsController

  def sign_up_params
    new_params = devise_parameter_sanitizer.sanitize(:sign_up)

    # If no password is supplied for new user, create one
    # This is needed because Devise requires a password for Rememberable to work,
    # even if password_required? is set to false in the User model.
    if (new_params[:password] == nil)
      new_params[:password] = Devise.friendly_token
    end

    # return the modified (and further sanitized) params list
    new_params
  end
end

取决于您尝试做什么,是否要让用户了解他们拥有的临时密码,这取决于您。或者,如果他们以后添加了一个电子邮件地址,也可以让他们重置它,这也会导致他们确认他们的电子邮件地址。