フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

expressでpassportログイン認証(セッション)を試してみる

passport

公式ドキュメント

 インストールと前準備

  • ID、パスワードをセッションに格納してログイン認証する
npm install passport
npm install passport-local
npm install --save express-session
  • ログイン認証を一時的に試したくフォームを作るためにtemplateエンジンをインストール
npm install ejs
  • expressのデフォルトの設定はAPIモードなので、POSTメソッドを受け取れるように下記の記述と既存のソースのコメントアウトをする
//app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

実装

index.jsファイルに下記の記述をする

const passport = require('passport');
const LocalStrategy = require("passport-local").Strategy;
passport.use("local",
  new LocalStrategy({
    usernameField: "username", 
    passwordField: "password", 
  },(username,password,done) => {  
    if(username==="test_user" && password==="password"){
      let profile = {id: 1, name: 'test'}
      return done(null,profile);
    }else{
      return done(null,false);
    }
  })
);

app.use(passport.initialize());
app.use(session({ secret: 'hogehoge' }));
app.use(passport.session());

app.get('/login', function(req, res){
    const message = "FORM";
    res.render("login", {message: message});
});

app.get('/mypage', function(req, res){
    const message = "Mypage";
    res.render("mypage", {message:  JSON.stringify(req.session)});
});

app.post("/login",passport.authenticate(
    "local",
    {
      successRedirect: "/mypage",
      failureRedirect: "/login",
      session: true 
    }
 ));
  
passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
  ## ユーザー情報に付属する、その他の情報などが必要であれば取得して、加工して返す
  ## 特に利用しないければ必要ない「serializeUser」メソッドを実行しておけばOK
  done(null, user);
});

フォーム

ejsをインストールしたのでログインフォームを作成する. views/index.ejsファイルを下記のように作成する

<!doctype html>
<html lang="jp">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <title>ログインフォーム</title>
  </head>
  <body>
    <p><%= message %></p>
    <form action="/login" method="post">
        <div>
            <label>Username:</label>
            <input type="text" name="username"/>
        </div>
        <div>
            <label>Password:</label>
            <input type="password" name="password"/>
        </div>
        <div>
            <input type="submit" value="Log In"/>
        </div>
    </form>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  </body>
</html>

ログイン認証したい場合

下記のようにチェック関数を作成して、認証確認したいルーティングに引数としてわたすことでログイン認証をすることができます。

const loginCheck = function(req, res, next) {
  if (req.session.passport) {
    next();
  } else {
    res.redirect('/login');
  }
};
app.get('/mypage', loginCheck,function(req, res){
    res.render("ok", {message:  JSON.stringify(req.session.passport)});
});

おまけ

var cb0 = function (req, res, next) {
  logger.app.debug("STEP1")
  next()
}

var cb1 = function (req, res, next) {
  logger.app.debug("STEP2")
  next()
}

app.get('/example', [cb0, cb1], function (req, res, next) {
  logger.app.debug("STEP3")
  next()
}, function (req, res) {
  logger.app.debug("STEP4")
  res.send('view')
})

参考にさせて頂いたページ

https://qiita.com/itagakishintaro/items/e5a0481b51e6a17b304c
https://qiita.com/hika7719/items/3282ab2ebcdaf080912e
https://qiita.com/moomooya/items/00f89e425a3034b8ea14