可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using devise
gem, after clicking on the confirmation link, I want to directly sign-in. At present it is asking to sign-in again.
Recently I have added the following in the devise initialize file:
config.allow_insecure_token_lookup = true
config.secret_key = 'a8d814803c0bcc735ce657adc77793459d00154cdd7532c13d3489600dc4e963f86e14beb593a32cbe9dbbe9197c9ce50a30102f363d90350052dc8d69930033'
Any suggestions?
回答1:
In previous Devise versions, the user was automatically signed in after confirmation. This meant that anyone that could access the confirmation e-mail could sign into someone’s account by simply clicking the link.
Automatically signing the user in could also be harmful in the e-mail reconfirmation workflow. Imagine that a user decides to change his e-mail address and, while doing so, he makes a typo on the new e-mail address. An e-mail will be sent to another address which, with the token in hands, would be able to sign in into that account.
If the user corrects the e-mail straight away, no harm will be done. But if not, someone else could sign into that account and the user would not know that it happened.
For this reason, Devise 3.1
no longer signs the user automatically in after confirmation. You can temporarily bring the old behavior back after upgrading by setting the following in your config/initializers/devise.rb:
config.allow_insecure_sign_in_after_confirmation = true
This option will be available only temporarily to aid migration.
回答2:
The config.allow_insecure_sign_in_after_confirmation
flag is no longer supported in Devise.
While you should be aware of the possible security concerns of automatically logging users in when they confirm their account (http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/), for some apps the benefit in terms of user experience may be worth the security tradeoff.
After all, the security risk is that a) the user mis-types their email, b) they don't immediately correct their mistake, c) the email they typed corresponds to a valid and working email, d) the person who incorrectly receives the email opens it and clicks the link.
If this is an acceptable risk profile for your application, you can override the devise 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
And route to it in your routes.rb
:
devise_for :users, controllers: { confirmations: 'confirmations' }
回答3:
With more recent versions of Devise, you can do the following.
config/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
回答4:
Looking at mb21's answer, it should be
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 is the time the email was sent to the user, as opposed to confirmed_at, which is the moment the user clicks the link, which is always within 2 hours of now on the server when it happens...
回答5:
We wanted the user so sign in automatically if she clicks the link in the email 2 hours or less after user creation. Based on @Sjor's answer, we went with:
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
回答6:
Here you have how you can solve it.
This code will allow the user to automatically sign-in after confirming, only if is the first time confirming his/her account.
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