はじめに
本記事では、本格的なAPI開発では避けては通れない認証をNode.jsで実装する方法を解説します。チュートリアル形式になっているので最初から手順通り進めていけば、実際のアプリケーションに認証を導入する方法が理解できるようになっています!
サンプルコードはこちらからどうぞ!
準備
以下のツールを使います。インストールしてない方はリンク元からインストールしてください!
作るもの
認証付きAPIサーバを構築します。以下の2つのルートを作成します。
[POST] /api/login
ユーザ名とパスワードをリクエストするとトークンが返ってくるエンドポイント。
[GET] /api/me
トークンを付与してリクエストすると認証したユーザのデータが返ってくるエンドポイント。
プロジェクト作成
プロジェクトフォルダを作成します。ここではプロジェクト名をexpress-api-jwtとします。
mkdir express-api-jwt
cd express-api-jwt
プロジェクトフォルダをnpmで初期化します。
npm init
色々聞かれますが、全てEnterを押して次に進みます。初期化が終わるとプロジェクトフォルダにpackage.jsonが作成されます。
次にExpressなど必要なパッケージをインストールします。
npm install express body-parser morgan mongoose jsonwebtoken --save
簡単にパッケージの説明をしておきます。詳しくはググってください。
- expressはNode.js上で動く人気のフレームワークです。ドキュメントはこちら
- mongooseは、MongoDBデータベースとやり取りするためのパッケージです。
- morganはリクエストをコンソール上に表示して可視化してくれるパッケージです。
- body-parserはリクエストからパラメータを取り出してくれるパッケージです。
- jsonwebtokenはJSON Web Tokenを発行したり認証してくれるパッケージです。
プロジェクトフォルダにindex.jsというファイルを作成して以下のように記述してみましょう。
// パッケージの読み込み
var express = require('express');
var app = express();
var morgan = require('morgan');
var port = process.env.PORT || 8080;
app.use(morgan('dev'));
var apiRoutes = express.Router();
// ルートに/apiプレフィックスをつける
app.use('/api', apiRoutes);
// ルート
apiRoutes.get('/healthcheck', function(req, res){
res.send('hello world!');
});
app.listen(port);
console.log('サーバを起動しました。http://localhost:' + port);
ひとまずこの状態で立ち上げてみます。以下のコマンドを実行してみてください。
node index.js
※エラーが出る場合は以下のようにしてください。
sudo node index.js
画像のように表示されれば成功です。
ブラウザを開いて
http://localhost:8080/api/healthcheck
にアクセスしてみましょう。
またコンソールにもリクエストのログが表示されます。
以上でセットアップは完了です。
以降では認証方法の導入に入りますが、一つ注意点があります。Node.js上ではソースコードを変更した場合でも一度再起動しないと変更が反映されません。command + C(Windowsの場合はControl + C)でサーバを停止した後、再びnode index.jsをする必要があります。いちいちめんどくさいよ!って方は以下にNodemonを使った自動リロードの設定方法をまとめておいたので参考にしてください。
Nodemonを使ってNode.jsのソース変更毎に自動リロードする方法
Userモデルの作成
Userを作ったり取得するためにMongooseのモデルを定義します。
app/modelsディレクトリにuser.jsのファイルを作成してください。
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('User', new Schema({
name: String,
password: String,
}));
#設定ファイル作成
app/ディレクトリにconfig.jsという設定ファイルを作成して以下のようにしてください。
module.exports = {
'secret' : 'application-secret-key',
'database' : 'mongodb://localhost:27017/express-api-jwt',
}
MongoDBのインストール
MongoDBがまだ入っていない方は入れてください。
Macの場合
brew install mongodb
# mongoDBを自動起動
ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
Windowsの場合
MongoDB 3.0.6(Windows版)をインストールして起動するまでの手順
# ユーザデータ登録
プロジェクト作成の時に作ったindex.jsを以下のように書き換えます。
// パッケージ読み込み
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken');
var config = require('./config');
var User = require('./app/models/user');
var port = process.env.PORT || 8080;
// MongoDBに接続する
mongoose.connect(config.database, { useNewUrlParser : true});
app.set('secretKey', config.secret);
// body parserの設定
app.use(bodyParser.urlencoded({ extended: false}));
app.use(bodyParser.json());
// morganを使ってリクエストをコンソール上に出力できるようにする
app.use(morgan('dev'));
var apiRoutes = express.Router();
// ルートに/apiプレフィックスをつける
app.use('/api', apiRoutes);
// ルート
apiRoutes.get('/healthcheck', function(req, res){
res.send('hello world!');
});
apiRoutes.get('/signup', function(req, res) {
var user = new User({
name: 'サンプルユーザー',
password: 'password',
});
user.save(function(error){
if(error) {
throw error;
}
console.log('ユーザを作成しました。');
res.json({ success: true});
})
});
app.listen(port);
console.log('サーバを起動しました。http://localhost:' + port);
この状態でブラウザで
http://localhost:8080/api/signup
にアクセスしてみてください。
このように表示されれば成功です。
# 認証用ルートを作成する
[POST] /api/loginエンドポイントを作成します。index.jsに以下の記述を追加しましょう。
apiRoutes.post('/login', function(req, res) {
// リクエストパラメータから名前を取り出して検索する
User.findOne({
name: req.body.name
}, function(error, user) {
if (error) throw error;
if (user) {
// パスワードが正しいか確認します。
if (user.password != req.body.password) {
res.json({ success: false, message: 'パスワードが違います。' });
} else {
// ユーザとパスワードの組が正しければトークンを発行します。
// パスワードはpayloadの中に含めないように注意してください。
const payload = {
name : user.name
}
var token = jwt.sign(payload, app.get('secretKey'));
// トークンを返します。
res.json({
success: true,
token: token
});
}
} else {
res.json({ success: false, message: 'ユーザがいません。' });
}
});
});
書き上げたらPostmanで[POST] /api/loginにリクエストしてみます。
# 認証ミドルウェアの作成
app/middlewaresディレクトリにverifyToken.jsというファイルを作成しましょう。
var jwt = require('jsonwebtoken');
var config = require('../../config');
function verifyToken(req, res, next) {
// header か url parameters か post parametersからトークンを取得する
var token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {
// jwtの認証をする
jwt.verify(token, config.secret, function(error, decoded) {
if (error) {
return res.json({ success: false, message: 'トークンの認証に失敗しました。' });
} else {
// 認証に成功したらdecodeされた情報をrequestに保存する
req.decoded = decoded;
next();
}
});
} else {
// トークンがなければエラーを返す
return res.status(403).send({
success: false,
message: 'トークンがありません。',
});
}
}
module.exports = verifyToken;
認証付きルートを作成する
[GET] /api/meエンドポイントを作成します。index.jsに以下の記述を追加しましょう。
var VerifyToken = require('./app/middlewares/VerifyToken');
apiRoutes.get('/me', VerifyToken, function(req, res, next) {
User.findOne({name: req.decoded.name}, {password: 0},
function (error, user) {
if (error) return res.status(500).send("ユーザの取得に失敗しました。");
if (!user) return res.status(404).send("ユーザが見つかりません。");
res.status(200).send(user);
});
});
Postmanを開いて[GET] /api/meにアクセスしてみましょう。
headersのところにkey = x-access-token value=XXXXXXXXXXXXXX(/api/loginで得たtoken)
を設定しましょう。
画像のようにレスポンスが返って来れば成功です!
最後に
お疲れ様です。以上でこのチュートリアルは終わりです。
質問ありましたらお気軽にコメント欄へどうぞ。最後までお付き合いいただきありがとうございました!!

WINDII

最新記事 by WINDII (全て見る)
- Canvaが最高すぎる。使い方を完全ガイド【チュートリアルあり】 - 2019年5月14日
- 人気急上昇中のLaravelをはじめよう!【徹底解説】 - 2019年4月23日
- Laravelの認可を理解して実装してみよう! - 2019年3月29日
この記事へのコメントはありません。