Rails 5.2.1
Ruby 2.5.1
Devise 4.5.0
[事象]
deviseでメールを使ったパスワードリセットに失敗する。
Rails5.2.1 deviseのパスワードリセットに失敗する
メール受信後の流れ。
- メールのリセット用リンクをクリック。(リンクにはtokenがついている)
- Rails上でDevise.token_generator.digestのでURLのtokenパラメータを下に値生成
- 生成した値をもとにusers. reset_password_tokenの値を取得する(select * from users where reset_password_token = xxxx)
- DBからusers情報が取得できたらパスワード更新をする
4でusersの情報が取得できなくなっていた。
おかしい原因。reset_password_tokenで絞り込みした際にデータが取れていないのがおかしい。
失敗原因
reset_password_instructions.html.erb
<%= link_to t(‘.action’, :default => “Change my password”), edit_password_url(@resource, :reset_password_token => (Devise::VERSION.start_with?(‘3.’) ? @token : @resource.reset_password_token)) %>
:reset_password_token => (Devise::VERSION.start_with?(‘3.’) ? @token : @resource.reset_password_token)
ここは、devise4.5.0なので@resource.reset_password_tokenが設定されるが、上記の手順2でDevise.token_generator.digestで生成される場合は、@tokenの値を渡す必要がある。
@tokenが渡せるよう修正をする必要がある。
対策方法
app/views/devise/passwords/new.html.erb
に
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
があるが、password_pathはdeviseで準備されているメールテンプレートを使用ており
今回はRails内のメールテンプレートを使用したい。
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
↓↓
<%= form_for(resource, as: resource_name, url: user_password_path, html: { method: :post }) do |f| %>
に修正しよう。
これで、Railsのプロジェクト内のテンプレートで対応ができる。
そのまま使えると思ったら使えないものですねぇ。
何か参考になれば幸いです。