前回までで、開発環境を作成したので認証を試す。
share/Docker/express/Dockerfile.
FROM node:5.4.0
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
#gulpfileを書き出し
RUN echo "var requireDir = require('require-dir'); requireDir('webapp/gulp/tasks', { recurse: true }); " > gulpfile.js
#package.jsonを書き出し
RUN echo '{ "name": "node_express", "scripts": { "start": "node webapp/bin/www", "gulp":"gulp" }}' > package.json
#タスクランナーインストール
RUN npm install --save-dev gulp
RUN npm install --save-dev require-dir
RUN npm install --save-dev gulp-if
RUN npm install --save-dev gulp-livereload
#サーバーインストール
RUN npm install --save-dev express
RUN npm install --save-dev body-parser
RUN npm install --save-dev cookie-parser
RUN npm install --save-dev debug
RUN npm install --save-dev jade
RUN npm install --save-dev morgan
RUN npm install --save-dev serve-favicon
# ウェブソケットインストール
RUN npm install --save-dev socket.io
# DBドライバインストール
RUN npm install --save-dev mongodb
# 認証ミドルウェアインストール
RUN npm install --save-dev passport
RUN npm install --save-dev passport-local
CMD [ "npm","run","gulp", "--","watch" ]
share/shell/express_docker_start.sh
#!/bin/bash
source "/home/vagrant/share/shell/env.conf"
# 前回のコンテナが残っているかチェック。
docker ps -a | grep $containerName_express >/dev/null 2>&1
# コンテナが残っている場合は削除。
if [ $? -eq 0 ]; then
docker rm -f $containerName_express
fi
docker run --name $containerName_express --rm -it -p 80:3000 -p 35729:35729 -v $path_dev_dir/myExpressGenerator:/usr/src/app/webapp $imageName_express
dockerイメージを作成し、コンテナを作成する。
次に、ルーティングと認証の設定。
share/dev/myExpressGenerator/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
// ルート設定
var routes = require('./routes/index');
var users = require('./routes/users');
var insert = require('./routes/insert.js');
var login = require('./routes/login');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// 認証ミドルウェアpassportの初期化。
app.use(passport.initialize());
app.use('/', routes);
app.use('/users', users);
app.use('/insert', insert);
app.use('/login', login);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
share/dev/myExpressGenerator/views/login.jade
extends layout
block content
h1=title
p Welcome to #{title}
p#id_test test
form(action="/login", method="post")
div
label
ユーザーID:
input(type="text", name="username")
div
label
パスワード:
input(type="password", name="password")
div
input(type="submit", value="ログイン")
share/dev/myExpressGenerator/routes/login.js
var express = require('express');
var router = express.Router();
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
// テスト用ユーザー
var user = {id:"test", username:"user",password:"password"};
// 認証。
if(username===user.username && password===user.password){
return done(null, true);
}else{
return done(null, false, { message: 'ログインに失敗しました。' });
}
}
));
router.get('/',
function(req, res, next) {
res.render('login', { title: 'Login' });
});
router.post('/',
passport.authenticate('local', {failureRedirect: '/login',
failureFlash: false,
session: false }),
function(req, res, next){
res.send("login success");
}
);
module.exports = router;
これで、 http://192.168.50.10/login
にアクセスすると認証を試すことができる。
次に、セッションを試す。
share/Docker/express/Dockerfile.
FROM node:5.4.0
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
#gulpfileを書き出し
RUN echo "var requireDir = require('require-dir'); requireDir('webapp/gulp/tasks', { recurse: true }); " > gulpfile.js
#package.jsonを書き出し
RUN echo '{ "name": "node_express", "scripts": { "start": "node webapp/bin/www", "gulp":"gulp" }}' > package.json
#タスクランナーインストール
RUN npm install --save-dev gulp
RUN npm install --save-dev require-dir
RUN npm install --save-dev gulp-if
RUN npm install --save-dev gulp-livereload
#サーバーインストール
RUN npm install --save-dev express
RUN npm install --save-dev body-parser
RUN npm install --save-dev cookie-parser
RUN npm install --save-dev debug
RUN npm install --save-dev jade
RUN npm install --save-dev morgan
RUN npm install --save-dev serve-favicon
# ウェブソケットインストール
RUN npm install --save-dev socket.io
# DBドライバインストール
RUN npm install --save-dev mongodb
# 認証ミドルウェアインストール
RUN npm install --save-dev passport
RUN npm install --save-dev passport-local
#セッション管理ミドルウェアインストール
RUN npm install --save-dev express-session
CMD [ "npm","run","gulp", "--","watch" ]
share/dev/myExpressGenerator/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var session = require('express-session'); //セッション追加
// ルート設定
var routes = require('./routes/index');
var users = require('./routes/users');
var insert = require('./routes/insert.js');
var login = require('./routes/login');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// セッションミドルウェア設定
app.use(session({ resave:false,saveUninitialized:false, secret: 'keyboar cat' }));
// 認証ミドルウェアpassportの初期化。
app.use(passport.initialize());
app.use(passport.session()); // セッション追加
// ルーティング設定
app.use('/', routes);
app.use('/users', users);
app.use('/insert', insert);
app.use('/login', login);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
share/dev/myExpressGenerator/routes/login.js
var express = require('express');
var router = express.Router();
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
//データベースモック。
var db={
users:{
records:[{
id:"1",
username:"user",
password:"password",
name:"Hibohiboo"
}],
findById(id, cb) {
process.nextTick(() => {
var idx = id - 1;
var record=this.records[idx];
if (record) {
cb(null, record);
} else {
cb(new Error('User ' + id + ' does not exist'));
}
});
},
findByUsername(username, cb){
process.nextTick(()=> {
for (var i = 0, len = this.records.length; i < len; i++) {
var record = this.records[i];
if (record.username === username) {
return cb(null, record);
}
}
return cb(null, null);
});
}
}
}
passport.use(new LocalStrategy(
function(username, password, cb) {
db.users.findByUsername(username, function(err, user) {
if (err) { return cb(err); }
if (!user) { return cb(null, false); }
if (user.password != password) { return cb(null, false); }
return cb(null, user);
});
}
));
// Configure Passport authenticated session persistence.
passport.serializeUser(function(user, cb) {
cb(null, user.id);
});
passport.deserializeUser(function(id, cb) {
db.users.findById(id, function (err, user) {
if (err) { return cb(err); }
cb(null, user);
});
});
router.get('/',
function(req, res, next) {
res.render('login', { title: 'Login' });
});
router.post('/',
passport.authenticate('local', {
failureRedirect: '/login',
failureFlash: false}),
function(req, res, next){
res.render('login', { title: 'Login', user_name:req.user && req.user.name || "" });
}
);
module.exports = router;
extends layout
block content
h1= title
p Welcome to #{title}
p#id_test #{user_name}
form(action="/login", method="post")
div
label
ユーザーID:
input(type="text", name="username")
div
label
パスワード:
input(type="password", name="password")
div
input(type="submit", value="ログイン")
ログインすると、名前が表示される。
#参考サイト
document - passport
express-session
Node.js + Express.js + express-sessionでセッションにデータ格納する方法
express-4.x-local-example