Node.jsのpassportでログインからのリダイレクトが上手くいかない

丸1日かかってしまった。もう自前で実装するところだった。






現象


passportを使うとなぜか上手くリダイレクトされない。
2,3回ログイン処理をする必要がある。
調査を進めるとログインした後の認証確認処理(req.isAuthenticated())が失敗して再度ログイン画面に飛ばされていた。


対策



セッションを手動で保存する


express-sessionは処理が終わった後に値が変わっていたら保存するようになっているが、
その保存タイミングがリダイレクトを挟んだ場合リダイレクト先の処理が終わった後になるらしい。
つまり認証処理 → リダイレクト → リダイレクト先画面 → 認証チェック処理 となる場合
認証が通った後にpassportで使用しているセッション情報を保存していないので認証済みチェックに失敗していたということらしい。
認証に成功したタイミングでセッションを保存することで上手く動作するようになる。
非同期処理なので注意。

  router.get(
    "/auth",
    passport.authenticate("local", {
      failureRedirect: "/login",
    }),
    (req, res) => {
      // 認証成功した場合のコールバック
      req.session.save(() => {
        res.redirect("/next")
      })
    },
  )

req.session.save(() => {
    res.redirect("/next")
})
が肝

以下に書いてある。
https://github.com/jaredhanson/passport/issues/482

フォームからのログインをGETメソッドにする


POSTだと上手くいかなかった。
マニュアルが間違っているとかの情報をどこかで見た。

以下のように記述する。
<form method="get" action="/login/auth">
  <div>
    <div> ユーザーID</div>
    <input type="text" name="username">
  </div>
  <div>
    <div> パスワード</div>
    <input type="password" name="password">
  </div>
  <button type="submit">
    <span>ログイン</span>
  </button>
</form>


後はapp.useの順番は重要
ざっくりbodyparser, session, passportの順だったと思う。


2018年7月10日火曜日