あらすじ
SPA で認証機能を使いたいので練習します。
対象読者
- redux の middleware について大体わかる
- JWT について大体わかる
大体わからない場合は以下をご一読下さい
- http://qiita.com/kuy/items/c6784fe443f1d5c7bbdc
- http://qiita.com/nabeliwo/items/ac4b77324a9989e8e6bb
Server を用意する
サーバーに以下の機能を実装します。
- login に成功したら token を生成して返す
- token を使った API を call する事ができるようになる
- logout すると token を使った API を call しても失敗する
- 再度 login すると新しい token を生成して返す
% mkdir practice-react-redux-jwt && cd $_ % npm install --save express express-jwt errorhandler morgan body-parser jsonwebtoken % npm init -y
create server.js:
const SECRET_KEY = 'SECRET_KEY'; const logger = require('morgan'), http = require('http'), express = require('express'), errorhandler = require('errorhandler'), bodyParser = require('body-parser'), jwt = require('jsonwebtoken'), jwtCheck = require('express-jwt')({secret: SECRET_KEY}); const app = express(); const port = process.env.PORT || 3000; app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); if (process.env.NODE_ENV === 'development') { app.use(logger('dev')); app.use(errorhandler()) } app.get("/", function(req, res) { res.sendfile(__dirname + '/www/index.html'); }) app.get('/api/hello', function(req, res) { res.status(200).send('hello, public'); }); app.use('/api/private', jwtCheck); app.get('/api/private/hello', function(req, res) { res.status(200).send('hello, private'); }); app.post('/api/sessions', function(req, res) { const token = jwt.sign({name: 'username'}, SECRET_KEY, { expiresIn: 60*60*5 }); res.status(201).send({ id_token: token }); }); http.createServer(app).listen(port, function (err) { console.log('listening in http://localhost:' + port); });
今回は Frontend の解説がメインなので Backend は最小限の機能にしています。 JWT の実装としては気が狂っている感じがしますが練習用のサーバープログラムなのでご了承下さい。
http://qiita.com/kaiinui/items/21ec7cc8a1130a1a103a
動作確認
/api/hello
はいつでも call 可能
% curl http://localhost:3000/api/hello hello, public
/api/private/hello
へのアクセスには Token が必要
% curl http://localhost:3000/api/private/hello UnauthorizedError: No authorization token was found
token を取得する
% curl -X "POST" http://localhost:3000/api/sessions {"id_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidXNlcm5hbWUiLCJpYXQiOjE0NzYzNDAyNTUsImV4cCI6MTQ3NjM1ODI1NX0.8CDpnsFZGYHy47xHzodckY1DKUG6j1cpyKRbbzpx9oQ"}
token を使用して /api/private/hello
へのアクセスができる事を確認する
% TOKEN=`curl -X "POST" http://localhost:3000/api/sessions | jq .id_token -r` % curl -H "Authorization: Bearer ${TOKEN}" http://localhost:3000/api/private/hello hello, private
今回はサーバー側の実装を紹介しました。 次回はフロント側の実装を紹介します。