問題
- Deviseを使って、メール認証を行う。
- 送られてきた認証用メールのURLをクリックすると、Signinのページではなく、ダイレクトにログインされるようにしたい。
解決策
その前に
Do not sign the user in after confirmation
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.
Devise 3.1: Now with more secure defaults | Plataformatec Blogより
Devise 3.1以前のバージョンでは、認証のURLからそのままサインインすることは可能だったようですが、メールのtypoなどで、別のアドレスに誤送信された場合、メール認証のURLからダイレクトにログインできてしまうとアカウントの情報簡単に取得されてしまうので、3.1以降は廃止されているそうです。
それでもダイレクトログインしたい場合は、
※ config.allow_insecure_sign_in_after_confirmation = true
の方法はサポートしないようです。こちらの回答より。
ですので、
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
devise_for :users, controllers: { confirmations: 'confirmations' }
と記入することで実現できます。