From 5a73bb414fafca464eb6a0b3ff305bb98d3ece9c Mon Sep 17 00:00:00 2001 From: haturatu Date: Fri, 9 Aug 2024 20:57:38 +0900 Subject: first commit --- app.ts | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ deps.ts | 2 ++ generate_key.ts | 25 ++++++++++++++++ token_operations.ts | 63 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 app.ts create mode 100644 deps.ts create mode 100644 generate_key.ts create mode 100644 token_operations.ts diff --git a/app.ts b/app.ts new file mode 100644 index 0000000..c80d508 --- /dev/null +++ b/app.ts @@ -0,0 +1,84 @@ +import { Hono } from "https://deno.land/x/hono/mod.ts"; +import { create, verify } from "https://deno.land/x/djwt@v3.0.2/mod.ts"; +import { crypto } from "https://deno.land/std@0.140.0/crypto/mod.ts"; +import { serve } from "https://deno.land/std@0.224.0/http/server.ts"; + +const app = new Hono(); + +// シークレットキーをファイルから読み込む +const loadKey = async () => { + try { + const keyData = await Deno.readFile("secret.key"); + return await crypto.subtle.importKey( + "raw", + keyData, + { name: "HMAC", hash: "SHA-512" }, + true, + ["sign", "verify"] + ); + } catch (error) { + console.error("Error loading key:", error); + throw error; + } +}; + +// ユーザーのログイン処理 +app.post("/login", async (c) => { + try { + const { username, password } = await c.req.json(); + + // ユーザー認証のロジック (ここでは仮の認証を使用) + if (username === "usesr" && password === "password") { + const key = await loadKey(); + + // JWTを生成 + const jwt = await create( + { alg: "HS512", typ: "JWT" }, + { username: username }, + key + ); + + return c.json({ message: "Login successful", token: jwt }); + } else { + return c.json({ message: "Invalid username or password" }, 401); + } + } catch (error) { + console.error("Login error:", error); + return c.json({ message: "Internal Server Error", error: error.message }, 500); + } +}); + +// JWT検証 +app.use("*", async (c, next) => { + if (c.req.method === "POST" && c.req.url.includes("/login")) { + await next(); + return; + } + + try { + const authHeader = c.req.headers.get("Authorization"); + if (!authHeader) { + return c.json({ message: "Authorization header missing" }, 401); + } + + const token = authHeader.replace("Bearer ", ""); + const key = await loadKey(); + const payload = await verify(token, key); + + c.req.state = { payload }; + await next(); + } catch (error) { + console.error("JWT verification error:", error); + return c.json({ message: "Unauthorized", error: error.message }, 401); + } +}); + +app.get("/", (c) => { + return c.json({ message: "Hello, world!" }); +}); + +// Honoサーバーの起動 +const port = 8787; +console.log(`Server running on http://localhost:${port}`); +await serve(app.fetch, { port }); + diff --git a/deps.ts b/deps.ts new file mode 100644 index 0000000..ddbbca4 --- /dev/null +++ b/deps.ts @@ -0,0 +1,2 @@ +export { Hono } from "https://deno.land/x/hono/mod.ts"; +export { bearerAuth } from "https://deno.land/x/hono/bearer_auth.ts"; diff --git a/generate_key.ts b/generate_key.ts new file mode 100644 index 0000000..f241f6e --- /dev/null +++ b/generate_key.ts @@ -0,0 +1,25 @@ +import { crypto } from "https://deno.land/std@0.140.0/crypto/mod.ts"; + +const generateKey = async () => { + try { + // 32バイトのHMACキーを生成 + const key = await crypto.subtle.generateKey( + { name: "HMAC", hash: "SHA-512" }, + true, + ["sign", "verify"] + ); + + // キーをエクスポート + const exportedKey = await crypto.subtle.exportKey("raw", key); + const keyUint8Array = new Uint8Array(exportedKey); + + // キーをファイルに保存 + await Deno.writeFile("secret.key", keyUint8Array); + console.log("Secret key generated and saved to 'secret.key'."); + } catch (error) { + console.error("Error generating or saving key:", error); + } +}; + +await generateKey(); + diff --git a/token_operations.ts b/token_operations.ts new file mode 100644 index 0000000..0e5b85f --- /dev/null +++ b/token_operations.ts @@ -0,0 +1,63 @@ +import { create, verify } from "https://deno.land/x/djwt@v3.0.2/mod.ts"; +import { crypto } from "https://deno.land/std@0.140.0/crypto/mod.ts"; + +// シークレットキーをファイルから読み込む +const loadKey = async () => { + try { + const keyData = await Deno.readFile("secret.key"); + return await crypto.subtle.importKey( + "raw", + keyData, + { name: "HMAC", hash: "SHA-512" }, + true, + ["sign", "verify"] + ); + } catch (error) { + console.error("Error loading key:", error); + } +}; + +// JWTを生成する +const createToken = async (key: CryptoKey) => { + try { + const jwt = await create( + { alg: "HS512", typ: "JWT" }, // ヘッダー + { foo: "bar" }, // ペイロード + key // CryptoKey + ); + console.log("Generated JWT:", jwt); + return jwt; + } catch (error) { + console.error("Error creating token:", error); + } +}; + +// JWTを検証する +const verifyToken = async (token: string, key: CryptoKey) => { + try { + const payload = await verify(token, key); + console.log("Payload:", payload); + } catch (error) { + console.error("Error verifying token:", error); + } +}; + +const run = async () => { + try { + const key = await loadKey(); + if (!key) { + console.error("Failed to load key."); + return; + } + + const token = await createToken(key); + if (token) { + await verifyToken(token, key); + } + } catch (error) { + console.error("Error during token operations:", error); + } +}; + +await run(); + -- cgit v1.2.3