BtoBtoC(BtoBtoBでも可)向けのアプリの場合、そのアプリを提供している会社向けに管理画面を提供したいと考えることがあります。その管理画面では、利用企業が自分たちのデータについてだけメンテナンスできるようになります。
そのための管理画面を作成していきます。今回は前回のベースを踏まえて、認証処理を作っていきます。
ユーザはあらかじめ管理画面で作成する
今回は企業向けにカスタマイズしたアプリを販売する想定なので、ユーザ登録の仕組みはいりません。管理画面であらかじめユーザを作成し、そのIDとパスワードを担当者に提供します。
この時の注意点として「全体のデータを管理するロールを作成しておく」「担当者は個別に作成するロールに所属させる」という点があります。全体のデータを管理するロールを作成しておかないと、皆さんがSDK経由でデータの操作ができなくなってしまいます。そして担当者は変わったり、増減が考えられるため、ACLは担当者ではなくロール単位で設けるようにします。
今回は全体を管理するAdmin、AAA(クライアント企業)、BBB(クライアント企業)という3つのロールを作成しました。そして担当者 aUser01、bUser01を作成します。それぞれAAA、BBBというロールに属するものとします。
HTMLの編集
まずログインフォームを作ります。これは views/index.jade を編集します。Express generatorが生成する記法はJadeになっています。
extends layout block content h1 ログイン form(action='/sessions',method='post') div.form-group label(for='inputUserId') ユーザID input.form-control(type='text',name='userId') div.form-group label(for='inputPassword') パスワード input.form-control(type='password',name='password') button.btn.btn-default(type='submit') ログイン
また、views/layout.jadeを編集してBootstrapなどを読み込むようにします。
doctype html html head title= title link(rel='stylesheet', href='/vendors/bootstrap/dist/css/bootstrap.min.css') link(rel='stylesheet', href='/stylesheets/style.css') body div.container-fluid div.row block content script(src='/vendors/jquery/dist/jquery.min.js') script(src='/vendors/bootstrap/dist/js/bootstrap.min.js') script(src='/javascripts/app.js')
ルーティングの設定
Expressでのルーティングですが、app.jsに次のように記述して追加します。
var sessions = require('./routes/sessions'); app.use('/sessions', sessions);
そして routes/sessions.js の内容を次のように記述します。この場合、 POST /sessions へのアクセスが送られます。
let express = require('express'); let router = express.Router(); let ncmb = require('../libs/ncmb'); router.post('/', (req, res, next) => { }); module.exports = router;
セッション設定
Expressのデフォルトではセッションデータをサポートしていません。そこでexpress-sessionと永続化のためのconnect-nedb-sessionをインストールします。
npm install express-session --save npm install connect-nedb-session --save
そしてapp.js内に次のように記述します。
let session = require('express-session') let NedbStore = require('connect-nedb-session')(session); let config = require('./config'); app.use(session({ secret: config.secret, resave: false, saveUninitialized: false, cookie: { path: '/', httpOnly: true, maxAge: 365 * 24 * 3600 * 1000 }, store: new NedbStore({ filename: 'session.db' }) }));
最後に config.json にセッションを暗号化するためのキーを指定します。
{ "application_key": "6b1...b3a", "client_key": "c14...9f8", "secret": "yoursecret" }
これで req.session を使ってセッションデータが使えるようになりました。
ログイン処理を行う
ログイン処理は POST /sessions にて行います。ログイン後に受け取ったユーザオブジェクトをそのままセッションデータとして追加します。
router.post('/', (req, res, next) => { ncmb.User.login(req.body.userId, req.body.password) .then((user) => { req.session.user = user; res.redirect('/'); }) .catch(error => { res.status(401).render('error', {error: error}); }) });
ログイン判定を行う
ログイン判定はセッションのあるなしで判定します。
router.get('/', function(req, res, next) { let user = req.session.user || null; res.render('index', { user: user }); });
後は Jade のテンプレート側で user 変数で判定できます。
extends layout block content if !user # 未ログインの場合(フォームを表示) else div= user.userName p form(action='/logout',method='post') button.btn.btn-success ログアウト
ログアウト処理を行う
ログアウト処理は POST /logout にて処理をします。これは routes/index.js に記述します。ここでの注意点として、localStorageのデータを削除する必要があるということです。localStorage自体はWebブラウザ側の機能ですが、Node.jsでは擬似的に再現しています。これを削除しないとJavaScript SDKの中でデータを再現してしまいます。また、このlocalStorageのデータはExpressアプリケーションの中で共通になるので、別なブラウザで表示した際にもログイン状態になってしまいます。
let localStorage = new require("node-localstorage").LocalStorage("./scratch"); router.post('/logout', function(req, res, next) { delete req.session['user']; localStorage.removeItem(`NCMB/${ncmb.application_key}/currentUser`); res.redirect('/'); });
このように書いていくと、最初にユーザログインフォームが表示されます。
ログインするとユーザ名とログアウトボタンを表示されます。ログアウトすると再度フォームが表示されます。
これで認証処理ができるようになりました。次はログイン時にデータの登録処理が行えるようにしたいと思います。
ここまでのソースコードはNCMBMania/BtoB_Management at v0.1にアップロードしてあります。実装時の参考にしてください。