Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8845

React+ReduxアプリにNode.js(express)とJWTで認証・認可周りの処理を実装する①API側

$
0
0

はじめに

React+ReduxアプリケーションにNode.js(express)でAPIを作り、jsonwebtoken(JWT)で認証・認可周りの処理を実装してみました。今回はAPI側の実装の内容を書いていきます。
ソースコードはGitHubにありますので、参考にしてください。

使ったもの

  • Node(v12.15.0)
  • express(v4.17.1)
  • jsonwebtoken(v8.5.1)
  • body-parser(v1.19.1)
  • nodemon(v2.0.3)
  • REST Client(VSCodeの拡張機能)

ディレクトリ構成

root/
 ├ api/
 │  ├ login.js
 │  └ users.js
 ├ config/
 │  └ jwt.config.js
 ├ middlewares/
 │  └ verifyToken.js
 ├ app.js
 └ request.rest

作るもの

[POST] /api/v1/login

ユーザーIDとパスワードを付与してリクエストすれば、認証が通ればjwtでトークンを返す

[GET] /api/v1/users

トークンをヘッダーに付与してリクエストすれば、ユーザー情報を返す

プロジェクト作成

プロジェクト作成して、必要なパッケージをインストールします。

npm init -y
npm install --save express jsonwebtoken body-parser nodemon

app.jsを作成

とりあえずexpressを読み込んで、appで初期化して、app.listenで起動する普通の流れです。
ルーティングは別ファイルにするので、express.Routerを初期化してリターンします。

app.js
constexpress=require("express");constbodyParser=require("body-parser");constapp=express();app.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());app.use("/api/v1",(()=>{constrouter=express.Router();router.use("/login",require("./api/login.js"));router.use("/users",require("./api/users.js"));returnrouter;})());app.listen(5000,function(){console.log("Example app listening on port 5000!");});

login.jsを作成

認証は本来はデータベースから行うが今回は割愛します。

login.js
constrouter=require("express").Router();constjwt=require("jsonwebtoken");constconfig=require("../config/jwt.config");// POST /api/v1/loginrouter.post("/",(req,res)=>{// 本来はデータベースからユーザーIDとパスワードを認証するが割愛if(req.body.userId=="00001"&&req.body.passWord=="qwerty"){constpayload={userId:req.body.userId,};consttoken=jwt.sign(payload,config.jwt.secret,config.jwt.options);res.json({isSuccess:true,token:token,});}else{res.json({isSuccess:false,message:"ユーザーIDまたはパスワードが違います。",});}});module.exports=router;

jwt.config.jsに設定を記載する。

jwt.config.js
module.exports={jwt:{secret:"cdfa54a89e0fbd4596213bf175336cfe05a78a73383f6dab39b8d374e7dceba53630546ff4c998b7bab9e53eaab2519a48e970b094315cf7472b811e45c1ea29",options:{algorithm:"HS256",expiresIn:"20m",},},};

シークレットキーはコマンドプロンプトで以下入力で取得したものです。

node
require("crypto").randomBytes(64).toString("hex")

ログインリクエストを試してみる

nodemonをインストールしてあれば以下で起動できます。

nodemonapp.js

今回リクエストにはVSCodeの拡張機能の[REST Client]を使います。request.restファイルに以下のように記述すれば、
上部に[Send Request]が表示されるのでクリックすれば、リクエストできます。

request.rest
POSThttp://localhost:5000/api/v1/loginContent-Type:application/json{"userId":"00001","passWord":"qwerty"}

認証に成功すれば以下レスポンスがあると思います。これでトークンが取得できましたで、ユーザー情報を取得します。

{"isSuccess":true,"token":"xxxxxxxxxxxxxxxxxxxx"}

verifyToken.jsを作成

まずトークンを認証するミドルウェアを作成します。
リクエストヘッダーには以下のようにトークンを付与します。

Authorization: Bearer xxxxxxxxxxxxxxxxxxxx

ヘッダーからトークンを取得して認証処理を行います。
認証が成功したら、req.decodedにpayloadで設定した値が格納される。

verifyToken.js
constjwt=require("jsonwebtoken");constconfig=require("../config/jwt.config");functionverifyToken(req,res,next){// splitで半角スペースで分割して後ろ側がTokenになるconstauthHeader=req.headers.authorization;consttoken=authHeader&&authHeader.split("")[1];if(token){jwt.verify(token,config.jwt.secret,function(error,decoded){if(error){returnres.status(403).send({isSuccess:false,message:"トークンの認証に失敗しました。",});}else{req.decoded=decoded;next();}});}else{returnres.status(401).send({isSuccess:false,message:"トークンがありません。",});}}module.exports=verifyToken;

users.jsを作成

こちらもは本来はデータベースから情報を取得するが今回は割愛します。
先ほど作成した[verifyToken]を付与すれば、認証が行われ[req.decoded]にユーザーIDが格納されるので、その値をもとにユーザー情報を取得してレスポンスを返します。

login.js
constrouter=require("express").Router();constverifyToken=require("../middlewares/verifyToken");// GET /api/v1/usersrouter.get("/",verifyToken,(req,res)=>{// 本来はデータベースからユーザーIDを元にデータを取得するが割愛letresults={};if(req.decoded.userId=="00001"){results={userId:req.decoded.userId,name:"Tom",};}res.json(results);});module.exports=router;

ユーザー情報取得リクエストを試してみる

先ほどログインした時のトークンをリクエストヘッダーに付与して、リクエストする。

request.rest
GEThttp://localhost:5000/api/v1/usersAuthorization:Bearerxxxxxxxxxxxxxxxxxxxx

認証に成功すれば以下のようにレスポンスがあるはずです。

{"userId":"00001","name":"Tom"}

まとめ

これで、API側の実装は完了です。本来はデータベースが必須になるのでそのうちMySqlかMongoDBあたりで実装するかもしれません。
とりあえず次回はフロント側の実装をしていきたいと思います。何かまずいところあればコメントお願いします。

参考にしたもの

Introduction to JSON Web Tokens
JWT Authentication Tutorial - Node.js


Viewing all articles
Browse latest Browse all 8845

Trending Articles