确认链接点击使用设计宝石后避免登录?

时间:2013-09-06 10:14:42

标签: ruby-on-rails ruby-on-rails-3 devise devise-confirmable

我正在使用devise gem,点击确认链接后,我想直接登录。目前要求再次登录。

最近我在设计初始化文件中添加了以下内容:

config.allow_insecure_token_lookup = true
config.secret_key = 'a8d814803c0bcc735ce657adc77793459d00154cdd7532c13d3489600dc4e963f86e14beb593a32cbe9dbbe9197c9ce50a30102f363d90350052dc8d69930033'

有什么建议吗?

6 个答案:

答案 0 :(得分:59)

在以前的Devise版本中,用户在确认后自动登录。这意味着任何可以访问确认电子邮件的人都可以通过单击链接登录某人的帐户。

在电子邮件重新确认工作流程中自动签名用户也可能有害。想象一下,用户决定更改他的电子邮件地址,并在这样做时,他在新的电子邮件地址上输入错误。电子邮件将被发送到另一个地址,该地址可以通过手中的令牌登录该帐户。

如果用户立即更正了电子邮件,则不会造成任何伤害。但如果没有,其他人可以登录该帐户,用户不会知道它发生了。

出于这个原因,Devise 3.1在确认后不再自动签署用户。通过在config / initializers / devise.rb中设置以下内容,可以在升级后暂时恢复旧行为:

config.allow_insecure_sign_in_after_confirmation = true

此选项仅暂时可用于帮助迁移。

答案 1 :(得分:52)

Devise中不再支持config.allow_insecure_sign_in_after_confirmation标志。

虽然您应该了解在用户确认帐户时自动记录用户可能存在的安全问题(http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/),但对于某些应用,用户体验方面的好处可能值得进行安全性权衡。

毕竟,安全风险是:a)用户误输了他们的电子邮件,b)他们没有立即纠正他们的错误,c)他们输入的电子邮件对应于有效且有效的电子邮件,d)该人错误接收电子邮件的人会打开它并点击该链接。

如果这是您的应用程序可接受的风险配置文件,您可以覆盖设计ConfirmationsController:

class ConfirmationsController < Devise::ConfirmationsController
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])
    yield resource if block_given?

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_flashing_format?
      sign_in(resource) # <= THIS LINE ADDED
      respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
    else
      respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
    end
  end
end

并在routes.rb中找到它:

devise_for :users, controllers: { confirmations: 'confirmations' }

答案 2 :(得分:15)

使用更新版本的Device,您可以执行以下操作。

配置/ routes.rb中

devise_for :users, controllers: { confirmations: 'users/confirmations' }

app / controllers / users / confirmations controller.rb

class Users::ConfirmationsController < Devise::ConfirmationsController
  def show
    super do |resource|
      sign_in(resource)
    end
  end
end

答案 3 :(得分:3)

看看mb21的答案,应该是

def show
  super do |resource|
    if resource.confirmation_sent_at > DateTime.now-2.hours && resource.errors.empty?
      sign_in(resource)
    end
  end
end

confirmation_sent_at是电子邮件发送给用户的时间,而不是confirm_at,这是用户点击链接的时刻,当发生时,它始终在服务器上的2小时内...

答案 4 :(得分:1)

我们希望用户在用户创建后2小时或更短时间点击电子邮件中的链接时自动登录。根据@ Sjor的回答,我们选择了:

class ConfirmationsController < Devise::ConfirmationsController
  def show
    super do |resource|
      if resource.confirmed_at > DateTime.now-2.hours && resource.errors.empty?
        sign_in(resource)
      end
    end
  end
end

答案 5 :(得分:1)

这里您有解决方法。

此代码将允许用户在确认后自动登录,只有在首次确认其帐户时。

class ConfirmationsController < Devise::ConfirmationsController
  before_action :maybe_auto_sign_in, only: :show

  protected

  def after_confirmation_path_for(resource_name, resource)
    sign_in(resource) if @auto_sign_in
    super
  end

  private

  # Automatically sign in the user that confirmed his/her email first time.
  def maybe_auto_sign_in
    @auto_sign_in =
      User.first_time_confirming?(params[:confirmation_token])
  end
end

class User < ActiveRecord::Base
  def self.first_time_confirming?(confirmation_token)
    confirmation_token &&
      User.where(confirmation_token: confirmation_token, unconfirmed_email: nil)
          .exists?
  end
end