LoginSignup
5

More than 3 years have passed since last update.

[Rails]deviseでreset_password_tokenが不正と言われる

Posted at

先に結論

devise-i18n-viewsの影響で、ユーザーのパスワード変更が出来なかった。
READMEにもかいてあるが、このgemはdevise-i18nにマージされたのでこっちを使うようにする。

環境

  • rails 5.2.3
  • devise 4.6.2
  • devise-i18n 1.8.0
  • devise-i18n-views 今回これが要らなかった話

何が起こった

deviseで管理しているモデルのパスワード変更をしようとしたらトークンが不正だと言われる。

  1. ログイン画面から「パスワードを忘れた」をクリック
  2. 登録されているメールアドレスを入力して送信
  3. 確認メール内のリンクをクリック
  4. パスワード再設定のフォームが開くので、新しいパスワードを入力
  5. reset_password_tokenが不正だと言われる orz

調査

「rails devise reset_password_by_token invalid」とかでググってみると、この手の話題は幾つか見つかった。
このissueとか参考になった。
具体的に、deviseはreset_password_tokenを作成するときに、以下のようなコードになっていた。

def set_reset_password_token
  raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)

  self.reset_password_token   = enc
  self.reset_password_sent_at = Time.now.utc
  save(validate: false)
  raw
end

https://github.com/plataformatec/devise/blob/master/lib/devise/models/recoverable.rb#L89

で、この戻り値 rawを受け取ってパスワードリセットメールを送信している

def send_reset_password_instructions
  token = set_reset_password_token
  send_reset_password_instructions_notification(token)

  token
end

この処理を見ると、実際はDBに保存されている reset_password_tokenの値とパスワードリセットのメールに記載されているreset_password_tokenは違うものだった

localhost:3000/users/password/edit?reset_password_token=vu9utDw1Mri848sEqPYf ←これ

issueにも書いてある通り、このリンクが書いてあるのはviewのmailer配下なので、問題があるとすればここだと思った。

が、今回はdeviseのファイルを翻訳するために

  • devise-i18n
  • devise-i18n-views

というgemを入れていた。

devise-i18n-viewsのソースコードを調べたところ、 ここが原因となっていた。

(Devise::VERSION.start_with?('3.') ? @token : @resource.reset_password_token)

deviseは4.6.2なのでfalseが実行されていた。。。

対応

  1. Gemfileからdevise-i18n-viewsを削除
  2. bundle update
  3. bundle clean

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5