Sequelizeを使う準備が整ったところで、どんなWebアプリを作るにしても避けて通れないであろうユーザー認証の仕組みを実装していく。
大まかな流れはこんな感じ。
Userモデルを定義する- 認証モジュールを設計する
- リクエストのルーティングを追加する
- 認証モジュールを実装する
はじめにアプリケーションのディレクトリ構造がどうなっているかおさらい。
myrest/ ├── app.js ├── config/ │ └── development.json ├── libs/ │ ├── dbconn/ │ └── models/ ├── models/ │ └── user.js ├── node_modules/ ├── package.json └── routes/ ├── index.js └── sync.js
Userモデルを定義する
Userモデルはmodels/user.jsで以下のように定義していた。
module.exports = function(sequelize, DataTypes) {
return sequelize.define('user', {
username: DataTypes.STRING
, password: 'char(40)'
});
};
ユーザーを認証する際はusernameカラムがキーになるので、UNIQUE制約を追加しておく必要がある。
passwordカラムは40バイトの固定長としているのは、SHA-1のハッシュ値(160bit)を16進数で格納するためだ。平文のパスワードからハッシュ値を計算する関数はいずれ必要になるので、Userモデルのクラスメソッドとして実装しておく。
module.exports = function(sequelize, DataTypes) {
return sequelize.define('user', {
username: {
type: DataTypes.STRING
, unique: true
}
, password: 'char(40)'
}, // End of table definition
{
classMethods: {
hashPassword: function(pass) {
var sha1 = require('crypto').createHash('sha1');
sha1.update(pass, 'utf8');
return sha1.digest('hex');
}
}
});
};
こうしておくことで、Userモデルを参照できるところでは、User.hashPassword()を呼び出せるようになる。
認証モジュールを設計する
実装する認証機能はサインアップ、ログイン、ログアウトの基本的なものだけにしておく。facebook連携とかパスワードリマインダーとか、認証モジュールの仕事はたくさんあるけどね。
まずroutes/auth.jsに認証モジュールの枠組みだけ作ってしまおう。
module.exports = function(models) {
var User = models.user;
return {
signup: function(req, res) {
}
, login: function(req, res) {
}
, logout: function(req, res) {
}
};
};
routes/authモジュールは、modelsオブジェクトを引数に受け取り、認証機能を提供するオブジェクトを返す関数として実装する。
signupメソッドでusersテーブルに新規データを登録。loginメソッドで認証処理を行いセッションを使ってログイン状態を保存する。logoutメソッドはセッションの破棄を行うだけ。
各メソッドの中身は実装編にて。
リクエストのルーティングを追加する
routes/index.jsでroutes/authモジュールの各メソッドにルーティングするコードを追加する。
module.exports = function(app, config) {
var sequelize = require('dbconn')(config)
, models = require('models')(sequelize);
// Database migration
app.configure('development', function() {
var sync = require('./sync');
app.post('/devel/sync/:table', sync.one(models));
app.post('/devel/sync', sync.all(sequelize));
});
// Authentication
var auth = require('./auth')(models);
app.post('/auth/signup', auth.signup);
app.post('/auth/login', auth.login);
app.post('/auth/logout', auth.logout);
};
すべてPOSTメソッドのみルーティングして、入力となるデータはexpressが提供するrequest.body経由で取得するようになる。
実装編へ続く…
1 コメント