Express.js + Session + Sequelizeで簡易ログイン(SessionStore利用)

ログインした情報をクライアントからサーバーに問い合わせる周りでSessionStoreを利用した。
Userモデルにユーザーの情報が入ってる場合を想定すると、こんな感じになるかな。
`ブラウザとかでcurrentUserを取りたいケース。expressのsessionはcookieにsessionID持ってて、そのsessionID使ってsession storeからuserIDを取得して、そのuserIDでUserモデルから引っ張る、っていう感じの流れ`

今回は簡単にSessionStoreの使い方だけ確認する。よくあるMongoDBではなく、mysql使うのでSequelizeを使った。

sessionにはexpress-sessionを利用。
https://github.com/expressjs/session
express-sessionで、SessionStoreをsequelizeと繋いで使うのに、[connect-session-sequelize](https://www.npmjs.com/package/connect-session-sequelize)を利用した。


```bash
$ express -e SessionSequelizeLoginProt
$ npm install --save sequelize express-session mysql connect-session-sequelize
$ npm install
```

migrationで簡単にSessionsテーブルを作っておく。(defineしてsyncしてテーブル作成でも可。)

```bash
$ sequelize model:create --name Session --attributes 'expires:date, data:string'
```

カラムはsid, expires, dataとするので、migrationとmodelを少し書き換える。

```/migrations/20170507020032-create-session.js
'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Sessions', {
      sid: {
        allowNull: false,
        primaryKey: true,
        type: Sequelize.STRING
      },
      expires: {
        type: Sequelize.DATE
      },
      data: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('Sessions');
  }
};
```

```/models/session.js
'use strict';
module.exports = function(sequelize, DataTypes) {
  var Session = sequelize.define('Session', {
    sid: DataTypes.STRING,
    expires: DataTypes.DATE,
    data: DataTypes.STRING
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here
      }
    }
  });
  return Session;
};
```

これでテーブル作成。

```bash
$ sequelize db:migrate
```

次にapp.jsに書き込み。

```/app.js
const session = require('express-session');
const Sequelize = require('sequelize');
var env       = process.env.NODE_ENV || 'development';
var config    = require(__dirname + '/config/config.json')[env];


const SequelizeStore = require('connect-session-sequelize')(session.Store);
if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
  var sequelize = new Sequelize(config.database, config.username, config.password, config);
}

var Session = sequelize.define('Sessions', {
  sid: {
    type: Sequelize.STRING,
    primaryKey: true
  },
  expires: Sequelize.DATE,
  data: Sequelize.STRING
});



app.use(session({
	secret: 'hoge',
	store: new SequelizeStore({
		db: sequelize,
		host: 'localhost',
		table: 'Sessions'
	}),
	resave: true,
	saveUninitialized: true
}));
```

routes/index.jsにさっと書いていく。

```/routes/index.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
	if (!req.session.userName) {
		res.redirect('/login');
	}
  res.render('index', { userName: req.session.userName });
});

router.get('/login', function(req, res) {
	res.render('login');
});

router.post('/create', function(req, res) {
	req.session.userName = req.body.userName;
	res.redirect('/');
});

router.get('/logout', function(req, res) {
	req.session.destroy();
	console.log('deleted session');
	res.redirect('/');
})

module.exports = router;
```

最後にview。

```/views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>session login test</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  	<h1>Index Page</h1>
    <p>Welcome, <%= userName %></p>
	<p>
		<a href="/logout">Logout</a>
	</p>    
  </body>
</html>
```

```/views/login.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>session login test</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <h1>Login Page</h1>
  <form action="/create" method="post">
  	<input type="text" name="userName">
  	<button type="submit">Submit</button>
  </form>
  </body>
</html>
```

これでSessionStoreを使った簡易ログインもどきが完成。
コードはこちら。
https://github.com/mazeltov7/SessionSequelizeLoginProt