1
0

passport.jsでユーザー認証を実装してみた

Posted at

はじめに

Passportは、認証や認可を簡単に実装できるNode.js用ミドルウェアです。
非常に柔軟なPassportはExpressベースのWebアプリケーションで利用できるため、ローカル認証やTwitter、FaceBookなどの外部認証にも使用されます。
今回はその中のローカル認証機能を実装していきます。

・使用するライブラリのインストール

zsh
npm install passport passport-local bcrypt express-session

ストラテジの設定

はじめに、ストラテジの設定を行います。新しくconfigフォルダを作成し、その下のpassport.tsファイルに設定内容を記述します。

config/passport.ts
import passport from "passport";
import { Strategy as LocalStrategy } from "passport-local";
import { PrismaClient } from "@prisma/client";
import bcrypt from "bcrypt";

const prisma = new PrismaClient();

passport.use(
  new LocalStrategy(
    {
      usernameField: "email",
      passwordField: "password",
    },
    async (email, password, done) => {
      const user = await prisma.user.findUnique({
        where: {
          email,
        },
      });

      if (!user) {
        return done(null, false, { message: "Incorrect email or password." });
      }

      const isMatch = await bcrypt.compare(password, user.password);
      if (!isMatch) {
        return done(null, false, { message: "Incorrect email or password." });
      }

      return done(null, user);
    }
  )
);

ローカル認証ストラテジにはユーザー名とパスワードを使用します。それぞれのフィールドの値はinputタグのname属性から取得していますので、認証にメールアドレスを使用したい場合は、以下のようにusernameFieldの値を変更することで可能になります。

config/passport.ts
{
    usernameField: "email",
    passwordField: "password",
}

リクエストと同時に渡されたデータを元にfunction(email, password, done) {}内で認証処理を行います。今回、認証処理にはprismaを使用し、データベース操作を行なっていきます。

シリアライズとデシリアライズの設定

passportJsにおけるシリアライズとは、認証後のユーザー情報をセッションに保存する機能であり、デシリアライズとは、セッションIDからユーザー情報を特定する機能になります。

これにより認証後のユーザー管理が容易になります。

config/passport.ts
//シリアライズの設定
passport.serializeUser((user: Express.User, done) => {
  done(null, user);
});

//デシリアライズの設定
passport.deserializeUser(async (user: User, done) => {
  const user = await prisma.user.findUnique({
    where: {
      id: user.id,
    },
  });

  if (!user) {
    return done(null, false);
  }

  done(null, user);
});

パスポートの初期化とセッション設定

app.use(passport.initialize())によりパスポートを初期化することで、認証として使われます。また、パスポートのセッションを設定することで、リクエストの度にデシリアライズされ、ユーザー情報がreq.userに格納されるようになります。

app.ts
import express from "express";
import passport from "passport";
import expressSession from "express-session";

const app = express();

const session = expressSession({
  secret: "your-secret-key",
  resave: false,
  saveUninitialized: false,
});

app.use(session);
app.use(passport.initialize());
app.use(passport.session());

/loginにリクエストとがあると、passport.authenticate()により認証を行います。第一引数にストラテジの指定を行います。今回はローカル認証の実装のため、"local"とします。

successRedirectは認証に成功すると指定のパスにページ遷移し、failureRedirectは失敗したときに遷移するページのパスを指定します。failureFlashはエラーが起こった場合のエラーメッセージを返すかどうかの指定になります。

app.ts
app.post('/login', passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect: '/login',
    failureFlash: false,
  }
));

今回はローカル認証の実装をご紹介していきましたが、Twitter、FaceBookなどの外部認証もパスポートを使用することで比較的容易に実装できるみたいなので是非チャレンジしてみてください!!

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