1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Node.js+Express+Passportでログイン認証をしたい

Last updated at Posted at 2020-03-22

はじめに

「Node.jsってどんなもんなんだろう?」ってところから始まり。
  ↓
「へぇ〜APIとか簡単にできるじゃん」となり。
  ↓
「ログイン認証とかも割と簡単なんじゃね」と思ったのでやってみました。

環境

  • macOS Mojave

Express

npmを使ってExpressをインストールする。
entry pointはapp.jsに設定する。

$ mkdir myapp
$ cd myapp
$ npm init
$ npm install express

myappにapp.jsを作成し、以下を実装する。

app.js
const express = require('express')
const app = express()

app.get('/', (req, res) => {
    res.send('Hello World')
})
    
app.listen(3000, () => {
  console.log('Listening on prot 3000')
})

普通にnode app.jsで起動しても良いが、変更に対して自動的に起動するようにしてほしいのでnodemonをインストールする。
起動したら、http://localhost:3000にアクセスし期待通りの動きをしているか確認する。

$ npm install nodemon -g
$ npx nodemon app.js
    [nodemon] starting `node app.js`
    Listening on prot 3000

Passport

ログイン認証に必要なものをインストールします。
(詳しく説明しませんが、ググれば大丈夫)

$ npm install body-parser
$ npm install cookie-parser
$ npm install express-session
$ npm install passport
$ npm install passport-local
$ npm install connect-ensure-login

publicフォルダを作成し、login.htmlok.htmlng.htmlを作成する

app.js
const express = require('express')
const app = express()
const path = require('path')
const session = require('express-session')
const passport = require('passport')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const LocalStrategy = require('passport-local').Strategy;

app.use(express.static(path.join(__dirname, 'public')))
app.use(cookieParser())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(session({ 
  secret: 'secret',
  resave: false,
  saveUninitialized: false,
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new LocalStrategy((username, password, done) => {
  if (username !== 'user' || password !== 'passwd') {
    return // ログイン失敗
  }
  return done(null, username) // ログイン成功
}))

passport.serializeUser((user, done) => {
  done(null, user)
})
passport.deserializeUser((user, done) => {
  done(null, user)
})
// ...
login.html
<html>
  <head lang="ja">
    <meta charset="UTF-8">
    <title>ログイン</title>
  </head>
  <body>
    <form action="/login" method="post">
      <div>
        <label>ユーザID:</label>
        <input type="text" name="username">
      </div>
      <div>
        <label>パスワード:</label>
        <input type="password" name="password">
      </div>
      <div>
        <input type="submit" value="Login">
      </div>
    </form>
  </body>
</html>

その他

ログインに成功したら/login/okへリダイレクト、失敗したら/login/ngへリダイレクトするような実装をします。
ただ、普通にやってしまうとログインに成功していないにも関わらず、http://localhost:3000/login/okと叩けばアクセスできてしまいます。。。
そこで便利なものがあります!
require('connect-ensure-login').ensureLoggedIn('/login')を挟んでやれば、ログインしていない場合は指定した/loginにリダイレクトされるようにできます。

app.js
// ...
app.get('/', (req, res) => {
  res.redirect('/login')
})

app.get('/login', (req, res) => {
  res.sendFile('login.html', { root: path.join(__dirname, 'public') })
})

app.post('/login',
  passport.authenticate('local', { failureRedirect: '/login/ng', session: true }),
      (req, res) => {
        res.redirect('/login/ok')
      }
)

app.get('/login/ng', (req, res) => {
  res.sendFile('ng.html', { root: path.join(__dirname, 'public') })
})

app.get('/login/ok', 
    require('connect-ensure-login').ensureLoggedIn('/login'), // <--- こいつ!!
        (req, res) => {
            res.sendFile('ok.html', { root: path.join(__dirname, 'public') })
});

app.get('/logout', (req, res) => {
  req.logout()
  res.redirect('/login')
})
// ...

最後に

ログイン認証のセッション管理などをreq.isAuthenticated()で制御させてみたんですけど、想定通りの動きはしなかった。。。

これからはconnect-ensure-loginを使っていこーっと
一応、ソースコードを載せておきます。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?