コンテンツにスキップ

JSON Webトークン(JWT)の検証

ヘッダーからJWTトークンを抽出し、デコードして、検証チェックを実装して確認します。

export default {
async fetch(request) {
// "Authorization: Bearer" ヘッダーからJWTトークンを抽出
function getJWTToken(request) {
const authorizationHeader = request.headers.get("Authorization");
if (authorizationHeader && authorizationHeader.startsWith("Bearer ")) {
return authorizationHeader.substring(7, authorizationHeader.length);
}
return null;
}
// JWTトークンが正しい形式であることを検証: header.payload.signature(例: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjE2MjI1MDAwMDB9.TldRGokRHJvG69SefbxIqAlQ6nnco6aLa3y7jsYXHMI")
function validateJWT(token) {
const [header, payload, signature] = token.split(".");
if (!header || !payload || !signature) {
throw new Error("無効なJWT形式");
}
// JWTペイロードとヘッダーをJSONにデコード
const decodedHeader = JSON.parse(atob(header));
const decodedPayload = JSON.parse(atob(payload));
// ここでJWT署名を検証するロジックを実装します。
// この例では、ペイロードをチェックする単純な検証を仮定しています。
// 次の行を実際の検証ロジックに置き換えてください。
// JWTトークンが期限切れでないことを確認(テストするには、期限切れのトークン "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjE2MjI1MDAwMDB9.TldRGokRHJvG69SefbxIqAlQ6nnco6aLa3y7jsYXHMI" を送信してみてください)
if (decodedPayload.exp < Math.floor(Date.now() / 1000)) {
throw new Error("JWTが期限切れです");
}
// 必要に応じて、さらに検証チェックを追加できます(発行者、受信者など)。
// また、カスタム関数を使用して実際の署名検証を実装します。
return true;
}
// JWTトークンを抽出する関数を実行
const jwtToken = getJWTToken(request);
// トークンが提供されていない場合、401 Forbiddenを返す
if (!jwtToken) {
return new Response("JWTトークンがありません", { status: 401 });
}
// トークンを検証する関数を実行
try {
const validToken = await validateJWT(jwtToken);
if (validToken) {
// トークンが有効な場合、実際のレスポンスを返す
// 2033年に期限切れになる有効なトークンの例は "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjIwMDExMjAwMDB9._qgQ_TMrGfYgOoA8HtTZwEGoj8zAPWxsz8CT1jEAGzo"
return fetch(request);
} else {
return new Response("無効なJWTトークン", { status: 401 });
}
} catch (error) {
return new Response("トークンの検証中にエラーが発生しました: " + error.message, {
status: 500,
});
}
},
};