fix: 修復 JWT token 驗證問題

- 統一 JWT 密鑰配置,解決簽名驗證失敗
- 修復 DRAMALING_JWT_SECRET 與 DRAMALING_SUPABASE_JWT_SECRET 不一致問題
- 現在 /api/auth/status 端點正常工作
- JWT token 生成和驗證使用相同密鑰

問題:IDX10503: Signature validation failed. Token does not have a kid.
解決:統一 GenerateJwtToken 和 Program.cs 中的密鑰變數

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
鄭沛軒 2025-09-17 01:21:20 +08:00
parent c44d3e170c
commit b9f6eb1237
22 changed files with 77 additions and 14 deletions

View File

@ -33,7 +33,8 @@
"Bash(cat:*)",
"Bash(git log:*)",
"Bash(git init:*)",
"Bash(git remote add:*)"
"Bash(git remote add:*)",
"Bash(sqlite3:*)"
],
"deny": [],
"ask": []

View File

@ -181,8 +181,9 @@ public class AuthController : ControllerBase
private string GenerateJwtToken(User user)
{
var jwtSecret = Environment.GetEnvironmentVariable("DRAMALING_JWT_SECRET")
?? "your-super-secret-jwt-key-that-should-be-at-least-256-bits-long";
var jwtSecret = Environment.GetEnvironmentVariable("DRAMALING_SUPABASE_JWT_SECRET")
?? Environment.GetEnvironmentVariable("DRAMALING_JWT_SECRET")
?? "dev-secret-minimum-32-characters-long-for-jwt-signing-in-development-mode-only";
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(jwtSecret);

View File

@ -1,3 +1,40 @@
{
"pages": {}
"pages": {
"/layout": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/css/app/layout.css",
"static/chunks/app/layout.js"
],
"/learn/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/learn/page.js"
],
"/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/page.js"
],
"/register/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/register/page.js"
],
"/dashboard/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/dashboard/page.js"
],
"/login/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/login/page.js"
],
"/_not-found/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/_not-found/page.js"
]
}
}

View File

@ -8,7 +8,10 @@
"static/development/_buildManifest.js",
"static/development/_ssgManifest.js"
],
"rootMainFiles": [],
"rootMainFiles": [
"static/chunks/webpack.js",
"static/chunks/main-app.js"
],
"rootMainFilesTree": {},
"pages": {
"/_app": []

Binary file not shown.

Binary file not shown.

View File

@ -1 +1,6 @@
{}
{
"/_not-found/page": "app/_not-found/page.js",
"/dashboard/page": "app/dashboard/page.js",
"/login/page": "app/login/page.js",
"/register/page": "app/register/page.js"
}

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,10 @@ globalThis.__BUILD_MANIFEST = {
"devFiles": [],
"ampDevFiles": [],
"lowPriorityFiles": [],
"rootMainFiles": [],
"rootMainFiles": [
"static/chunks/webpack.js",
"static/chunks/main-app.js"
],
"rootMainFilesTree": {},
"pages": {
"/_app": []

View File

@ -1 +1 @@
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{},\"appUsingSizeAdjust\":false,\"pagesUsingSizeAdjust\":false}"
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{\"/Users/jettcheng1018/code/dramaling-vocab-learning/frontend/app/layout\":[\"static/media/e4af272ccee01ff0-s.p.woff2\"]},\"appUsingSizeAdjust\":true,\"pagesUsingSizeAdjust\":false}"

View File

@ -1 +1 @@
{"pages":{},"app":{},"appUsingSizeAdjust":false,"pagesUsingSizeAdjust":false}
{"pages":{},"app":{"/Users/jettcheng1018/code/dramaling-vocab-learning/frontend/app/layout":["static/media/e4af272ccee01ff0-s.p.woff2"]},"appUsingSizeAdjust":true,"pagesUsingSizeAdjust":false}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"c":["webpack"],"r":[],"m":[]}

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("98616de372651724")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI5ODYxNmRlMzcyNjUxNzI0XCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;