expressにpassportを使って認証を組み込むことができます。
ミドルウエアは、ユーザーからのリクエストと、実現したいビジネスロジックの間に挟まる層です。
ビジネスロジックに認証ロジックを入れてしまうと、例えばブラウザからの認証とネイティブアプリからの認証のロジックをそれぞれ意識して書く必要があり、ビジネスロジックが複雑になってしまいます。
ミドルウエアとして分離しておけばシンプルに保つことができます。
前回の記事で使ったセッションもミドルウエアの1つなので、今回の認証のミドルウエアと組み合わせると、
[ユーザーからのリクエスト] → [認証を行うミドルウエア] → [認証情報のセッションへの保存] → [ビジネスロジック]
のように直列に情報を受け渡して処理することができます。
今回はシンプルにするために、セッションは使いません。
passportは、passport本体の他に、Strategyと呼ばれる認証方法を豊富に利用することができます。
GoogleやEntra IDなど、外部のIdentity Providerを利用することもできますし、DBに保存した独自のID/PWを使うこともできます。
今回は、IDとPWで認証を行う、passport-localを使用していきます。
passportにStrategyを指定するには、passport.useを利用します。
passport.use(new LocalStrategy( (username, password, done) => { if (username === 'testuser' && password === 'testpass') { return done(null, {id: 1, username: 'testuser', role: 'admin'}) } return done(null, false) } ));
インポートしたStrategyをnewする際に、Callbackとして、認証を行う関数を渡します。
今回は、ID/PWが特定の値のときに認証OKとして、認証されたユーザーをオブジェクトとして返す関数を指定しています
その後、done()コールバックを必ず呼びます。
認証に成功したときには、第二引数にユーザーを入れて、失敗したときにはfalseを入れます。
これで次のミドルウエアがパイプラインとして繋がっていき、複数のミドルウエアが連携して動作します。
import express from 'express' import passport from 'passport' import {Strategy as LocalStrategy} from 'passport-local' // asで別名をつける const app = express(); app.use(express.urlencoded({extended: false})) // フォームの値を読めるようにする設定 // passportでLocalStrategyを使う設定 // デフォルトではusername / passwordというフォームの値を認識する passport.use(new LocalStrategy( (username, password, done) => { if (username === 'testuser' && password === 'testpass') { return done(null, {id: 1, username: 'testuser', role: 'admin'}) } return done(null, false) } )); app.use(passport.initialize()); // passportをミドルウエアとして利用する app.post('/login', (req, res, next) => { console.log(req.body); next(); }, passport.authenticate('local', { session: false, // sessionを使わない設定 failureMessage: 'Login failed', }), (req, res) => { res.send({LoginUser : req.user}) // 認証成功後、認証されたユーザーがreq.userに格納される } ) app.listen(3000, () => { console.log('Server is running on port 3000') });