Edited at

Node.js + Express4 + Passport + pug でログイン認証画面を作る(エラー表示あり)

More than 1 year has passed since last update.


はじめに

Webアプリケーションを作ろうとすると何かと必要になってくるログイン認証画面。

今回はExpress4、Passport、pugを使ってエラーメッセージ(フラッシュメッセージ)が表示されるものが書けたのでメモ。

わざわざデータベースを使うのが面倒だったので一時的な配列にユーザを保持しています。

ScreenNameに「user1」、Passwordに「pass1」でログインできます。

動作確認にはNode.js v8.10.0を使用しました。

このコードはMITライセンスの基で改変・再配布できるものとします。


必要パッケージ


  • express

  • express-session

  • connect-flash

  • passport

  • body-parser

  • passport-local

  • pug


コード


server.js

const path = require('path');

const express = require('express');
const session = require('express-session');
const flash = require('connect-flash');
const passport = require('passport');
const bodyParser = require('body-parser');
const { Strategy : LocalStrategy } = require('passport-local');

const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(session({ name: 'test-sid', secret: 'hoge', resave: false, saveUninitialized: true }));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// db
class Users {
constructor() {
this.store = [];
}
create(id, screenName, password) {
this.store.push({ id, screenName, password });
}
find(key, value) {
return this.store.find(user => user[key] == value);
}
}
const users = new Users();
users.create('u1', 'user1', 'pass1');

// strategy
passport.use(new LocalStrategy({ usernameField: 'screenName' }, (screenName, password, done) => {
const user = users.find('screenName', screenName);
if (user == null) {
return done(null, false, { message: 'invalid screenName' });
}
if (user.password != password) {
return done(null, false, { message: 'invalid password' });
}

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

// passport
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
done(null, users.find('id', id));
});

// routings
app.get('/', (req, res) => {
if (!req.user) {
res.render('login', { error: req.flash('error') });
}
else {
res.render('home', { user: req.user });
}
});
app.post('/', passport.authenticate('local', {
successRedirect: '/', failureRedirect: '/', failureFlash: true, badRequestMessage: 'empty credentials' }));

app.listen(8080, () => {
console.log('listening on port: 8080');
});



views/login.pug

if error != ''

p Error: #{error}

h1 Login

form(method='post' action='/')
div
label(for='screen-name-input') ScreenName:
input(type='text' name='screenName' id='screen-name-input')
div
label(for='password-input') Password:
input(type='text' name='password' id='password-input')
button Login



views/home.pug

h1 home

p hello, #{user.screenName}


表示


image.png


おわりに

新しいES、皆さんもどんどん書きましょう!