Express+mongoose+passportでユーザー登録認証&セッション全部やる
使用するミドルウェア
これらを使用するとロジックをコーディングする必要がなくなる
- mongoose
- express-session
- passport
- passport-local
- passport-local-mongoose
- connect-mongo
setup
$ cd ~/ $ express userlogin $ cd userlogin $ npm install $ npm install express-session passport passport-local connect-mongo mongoose passport-local-mongoose
app.js
以下の内容を追加 * sessionをmongoose経由でmongodbで保存 * /api へのアクセスは認証を通す
app.js
var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var mongoose = require('mongoose');
app.js
mongoose.Promise = global.Promise; mongoose.connect("mongodb://localhost/dbname", {useMongoClient: true}); // 接続 // session store var MongoStore = require('connect-mongo')(session); app.use(session({ secret: config.secret.session, saveUninitialized: true, resave: true, store: new MongoStore({mongooseConnection: mongoose.connection}) })); app.use(passport.initialize()); app.use(passport.session()); var User = require("./models/user"); passport.use(new LocalStrategy(User.authenticate())); passport.serializeUser(User.serializeUser()); passport.deserializeUser(User.deserializeUser()); // view にセッション情報を渡す場合はこれ app.use(function(req,res,next){ res.locals = { user: req.user }; next(); }); // ユーザー登録&ログイン画面 var user = require('./routes/users'); app.use('/users',user); : :
データベース定義
models/user.js
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var passportLocalMongoose = require('passport-local-mongoose'); var userSchema = new Schema ({ username : String, password : String, active : Boolean }); userSchema.plugin(passportLocalMongoose); module.exports = mongoose.model('User', userSchema);
ユーザーコントローラー
routes/users.js
// 登録フォーム router.get('/signup', function(req, res, next){ res.render('user/signup', { title : 'User Sign up', user : { username : '', password : '' } }); });
// ログインフォーム router.get('/signin', function(req, res, next){ res.render('user/signin', { title : 'User Sign in', user : { username : '', password : '' } }); });
var User = require('../models/user'); // 登録実行 router.post('/signup', function(req, res, next){ User.register( new User({ username: req.body.username, password: req.body.password }), req.body.password, function(err, user){ if (err) { return res.render('user/signup', {title: 'User Sign up Error', user: req.body, error: err}); } var authenticate = User.authenticate(); authenticate(req.body.username, req.body.password, function(err, result) { if(err) { return res.render('user/signup', {title: 'User Sign up Error', user: req.body, error: err}); } res.render('user/index',{title:'User Signed in', result: result}); }); } ); });
// ログイン実行 router.post('/signin', passport.authenticate('local'), function(req, res) { res.redirect('/'); });
動作確認
/signup
登録フォーム username, password をサブミット。成功するとusersコレクションに登録され、sessionにUser情報が入る/signin
ログインフォーム 成功するとsessionに該当のUser情報が入る/mypage
でユーザー認証, セッションの情報を取得できる。認証が不正な場合は status 401でレスポンスする。- req.user に情報が入る(今回は全viewにセッション情報を渡すためres.localsに設定)