LoginSignup
2
0

More than 5 years have passed since last update.

["Internal Server Error"との闘い] koa(koa-session,koa-passport)でユーザー登録ページ

Last updated at Posted at 2018-01-27

koaフレームワークで、以下のミドルウェアとボディーパーサーを使用してセッションを使用したサイトを作成しています。
また、ユーザー管理DBはMongoDB(mongoose)を使用しています。

  • koa-session
  • koa-passport
  • koa-router
  • koa-static
  • async-busboy(ボディーパーサー)

ユーザー登録画面を作成において、使用済みIDチェックなどの処理は画面リロードなしで行うようFetch APIを使用しています。
特にユーザー登録に成功したときに、そのままサーバー側でログインした状態に移行したいなというときに、躓いたので備忘録としての投稿です。

ユーザー登録画面において、登録ボタン(signupButton)をクリックした際に、Fetch APIでPOSTリクエストを投げます。

クライアント
signupButton.onclick = async evt => {
    const res = await fetch('/signup', {
        method: 'POST',
        body: new FormData(signupForm)
    });
    const resText = await res.text();
    if(resText === 'exists') {
      // 使用済みID
    }
};
サーバー(Node.js)
router.post('/signup', async ctx => {
    const { fields } = await asyncBusboy(ctx.req);
    const id = fields.id;
    const pass = fields.pass;
    const confirmPass = fields.confirmPass;

    if (fields.id && fields.pass && fields.pass === fields.confirmPass) {
        try {
            // DB検索
            const user = await User.findOne({ id });
            if (user) {
                // 使用済みID
                ctx.body = 'exists';
            } else {
                // ユーザー登録
                const newUser = new User({ id, password });
                await newUser.save();
            }
        } catch (err) {
            // エラー
            ctx.body = 'error';
        }
    }
});

ここで、登録ボタンをクリックすると、ユーザー登録に成功したらそのまま自動的にログイン→ログイン後の画面に遷移したいと思い、コードを以下のように修正しました。

クライアント
// ...
    // 'success'だったら'/app'に遷移する処理追加
    if(resText === 'success') {
        location.href = '/app';  
    }
    if(resText === 'exists') {
      // 使用済みID
    }
// ...
サーバー(Node.js)
// ...
                // ユーザー登録
                const newUser = new User({ id, password });
                await newUser.save();
                await ctx.login(newUser); // passportのloginメソッドを実行し、ログイン状態に移行
                ctx.body = 'success'; // 'success'を返す
// ...

これでサーバー側でログイン済みの状態となるようですが、クライアント側は一応URLが'/app'になっているものの、Internal Server Errorと表示されてしまいます。
なぜかと調査すると、そう、クッキーが空のままなのです。
どうしたものかとひと悶着したのち、以下のようにFetch APIで一行付け足すだけで解決しました。

クライアント(ブラウザー)
// ...
    const res = await fetch('/signup', {
        method: 'POST',
        body: new FormData(signupForm),
        credentials: 'include' // ←これ追加
    });
// ...

これで、'/app'に遷移してもInternal Server Errorとならずにログイン後のページのコンテンツが表示されるようになりました。

2
0
0

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
2
0