作 ▸
TypeScriptでJSON Web Tokenの作成と検証を行う
JSON Web Tokenを使った認証みたいなものを実装したが、結局ボツになったので供養。
※記載の内容はDockerイメージ node:16-alpine
から作成したコンテナ内で動作確認してます。他のOSだと鍵の作り方が違うかも。
Node.js v16.13.0jsonwebtoken 8.5.1
準備
必要なものをインストールする。
npm install typescript jsonwebtoken @types/node @types/jsonwebtoken
npm install --save-dev ts-node
これを書いた時の各パッケージのバージョンは以下。
{
"dependencies": {
"@types/jsonwebtoken": "^8.5.5",
"@types/node": "^16.10.7",
"jsonwebtoken": "^8.5.1",
"typescript": "^4.4.4"
},
"devDependencies": {
"ts-node": "^10.4.0"
}
}
次に、以下コマンドで秘密鍵と公開鍵を作成。
openssl genrsa -out /path/to/private.key 2048
openssl rsa -in /path/to/private.key -pubout -out /path/to/public.key
実行
以下のソースコードを作成。JSON Web Tokenの作成と検証は、npmパッケージ jsonwebtoken
で行います。
import * as fs from 'fs';
import * as jwt from 'jsonwebtoken';
type TokenPayload = {
dempa: string;
};
// 鍵をファイルから読み込み
const _privateKey = fs.readFileSync('/path/to/private.key');
const _publicKey = fs.readFileSync('/path/to/public.key');
// トークン生成
const payload = {
dempa: 'yunyun',
};
const expirationSeconds = 60 * 5; // 有効期限5分 (秒)
const token = jwt.sign(payload, _privateKey, { expiresIn: expirationSeconds, algorithm: 'RS256' });
console.log('token ->', token);
// トークン検証
let decoded: TokenPayload;
try {
decoded = jwt.verify(token, _publicKey, { algorithms: ['RS256'] }) as TokenPayload;
} catch (e) {
if (e instanceof jwt.TokenExpiredError) {
console.error('トークンの有効期限が切れています。', e);
} else if (e instanceof jwt.JsonWebTokenError) {
console.error('トークンが不正です。', e);
} else {
console.error('トークンの検証でその他のエラーが発生しました。', e);
}
throw e;
}
console.log('decoded ->', decoded);
このコードを以下コマンドで実行。
npx ts-node token.ts
すると以下のように、JSON Web Tokenとペイロードが出力される。
token -> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZW1wYSI6Inl1bnl1biIsImlhdCI6MTYzNjE4ODE0MywiZXhwIjoxNjM2MTg4NDQzfQ.lBUq1RUzy9ZJ-Nb59AWeMudQgyeHuXM0M1gwy_tTUNOzWEwHWMmpPEROyDtpA8yehlJHKzNlSEArgY2Bf-r0EBJz06BGVexfgMyTm1roITE7gZAj0M4Y0Roe2Q2bcYbKtUeRztm28uBorDnvx2iPUqBN7irCj2etx8Y0obwwwMs4W7YPnkcDcaw1M2RhffBGe8pWOB6FB5wZPcYoHRxVXn-8DYVYcwmmsAY-FsG2G7wduGfhYExGUgNodND1gTeG_feH_TSgc9XMP-v1T-sZjM3_fRql36Rpb6_w_jRa6kKTMJkWTz1-NxgenTPkom1wB9ibCtNkPs1jE9fSWv0l7g
decoded -> { dempa: 'yunyun', iat: 1636188143, exp: 1636188443 }
上記のJSON Web Tokenは、実際に自分がこの方法で作成したものなので、jwt.ioで中身を見れるはず。
以上。