{"record":{"id":"a0d89af0fd53cb73","repo":"yikart/AiToEarn","slug":"token-a0d89a","errorCode":null,"errorMessage":"token不存在,需要管理员权限","messagePattern":"token不存在,需要管理员权限","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"project/aitoearn-electron/server/src/auth/manager.guard.ts","lineNumber":48,"sourceCode":"  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const isManager = this.reflector.getAllAndOverride<boolean>(\n      IS_MANAGER_KEY,\n      [context.getHandler(), context.getClass()],\n    );\n\n    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [\n      context.getHandler(),\n      context.getClass(),\n    ]);\n\n    if (!isManager || isPublic) {\n      return true;\n    }\n\n    const request = context.switchToHttp().getRequest();\n    const token = this.extractTokenFromHeader(request);\n    if (!token) {\n      throw new UnauthorizedException('token不存在,需要管理员权限');\n    }\n\n    try {\n      const payload = await this.jwtService.verifyAsync(token, {\n        secret: process.env.AUTH_SECRET,\n      });\n\n      if (!payload.isManager) {\n        throw new UnauthorizedException('需要管理员权限1');\n      }\n\n      request['user'] = payload;\n    } catch {\n      throw new UnauthorizedException('需要管理员权限2');\n    }\n    return true;\n  }\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/auth/manager.guard.ts#L30-L66","documentation":"ManagerGuard.canActivate extracts the bearer token and throws UnauthorizedException 'token不存在,需要管理员权限' when no token is present in the Authorization header. The endpoint requires manager-level JWT authentication and none was supplied.","triggerScenarios":"Calling a manager-protected route without an Authorization header, with an empty header, or with a header not matching 'Bearer <token>' so extraction yields undefined.","commonSituations":"Client forgot to attach the token after login; scripts/tools calling admin routes without auth configured; proxy or gateway stripping the Authorization header; malformed scheme names.","solutions":["Attach 'Authorization: Bearer <managerToken>' to the request.","Log in as a manager account to obtain a token with the isManager claim.","Verify no middleware/proxy strips the Authorization header.","Check the header format is exactly 'Bearer ' + token (single space)."],"exampleFix":"// before\nawait fetch('/admin/stats');\n// after\nawait fetch('/admin/stats', {\n  headers: { Authorization: `Bearer ${managerToken}` },\n});","handlingStrategy":"validation","validationCode":"function assertAuthHeader(token) {\n  if (!token) throw new Error('缺少管理员 token');\n  return { Authorization: `Bearer ${token}` };\n}","typeGuard":"function hasBearerToken(headers) {\n  const [type, token] = (headers.authorization ?? '').split(' ');\n  return type === 'Bearer' && Boolean(token);\n}","tryCatchPattern":"try {\n  await adminApi.call();\n} catch (e) {\n  if (e?.response?.status === 401 && e.message.includes('token不存在')) {\n    await loginAsManager(); // 附上 Authorization: Bearer <token> 后重试\n  } else throw e;\n}","preventionTips":["Always attach the Authorization header for manager routes via a shared HTTP client interceptor.","Log out/in cleanly to refresh stored manager tokens.","Verify reverse proxies forward the Authorization header.","Check header spelling/case and 'Bearer ' prefix with a single space."],"tags":["jwt","auth","guard","missing-token","http-401"],"backgroundTag":"missing-auth-token","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}