はじめに
Passportは、認証や認可を簡単に実装できるNode.js用ミドルウェアです。
非常に柔軟なPassportはExpressベースのWebアプリケーションで利用できるため、ローカル認証やTwitter、FaceBookなどの外部認証にも使用されます。
今回はその中のローカル認証機能を実装していきます。
・使用するライブラリのインストール
npm install passport passport-local bcrypt express-session
ストラテジの設定
はじめに、ストラテジの設定を行います。新しく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
の値を変更することで可能になります。
{
usernameField: "email",
passwordField: "password",
}
リクエストと同時に渡されたデータを元にfunction(email, password, done) {}
内で認証処理を行います。今回、認証処理にはprismaを使用し、データベース操作を行なっていきます。
シリアライズとデシリアライズの設定
passportJsにおけるシリアライズとは、認証後のユーザー情報をセッションに保存する機能であり、デシリアライズとは、セッションIDからユーザー情報を特定する機能になります。
これにより認証後のユーザー管理が容易になります。
//シリアライズの設定
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
に格納されるようになります。
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.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: false,
}
));
今回はローカル認証の実装をご紹介していきましたが、Twitter、FaceBookなどの外部認証もパスポートを使用することで比較的容易に実装できるみたいなので是非チャレンジしてみてください!!