JavaScriptだけでWebサイト開発

node.js + Express + mongodb系 + React でサービスを作るメモ

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に設定)
©ichi-bit