yikart/AiToEarn · error · UnauthorizedException

token不存在,需要管理员权限

Error message

token不存在,需要管理员权限

What it means

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.

Source

Thrown at project/aitoearn-electron/server/src/auth/manager.guard.ts:48

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isManager = this.reflector.getAllAndOverride<boolean>(
      IS_MANAGER_KEY,
      [context.getHandler(), context.getClass()],
    );

    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);

    if (!isManager || isPublic) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException('token不存在,需要管理员权限');
    }

    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: process.env.AUTH_SECRET,
      });

      if (!payload.isManager) {
        throw new UnauthorizedException('需要管理员权限1');
      }

      request['user'] = payload;
    } catch {
      throw new UnauthorizedException('需要管理员权限2');
    }
    return true;
  }

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Attach 'Authorization: Bearer <managerToken>' to the request.
  2. Log in as a manager account to obtain a token with the isManager claim.
  3. Verify no middleware/proxy strips the Authorization header.
  4. Check the header format is exactly 'Bearer ' + token (single space).

Example fix

// before
await fetch('/admin/stats');
// after
await fetch('/admin/stats', {
  headers: { Authorization: `Bearer ${managerToken}` },
});
Defensive patterns

Strategy: validation

Validate before calling

function assertAuthHeader(token) {
  if (!token) throw new Error('缺少管理员 token');
  return { Authorization: `Bearer ${token}` };
}

Type guard

function hasBearerToken(headers) {
  const [type, token] = (headers.authorization ?? '').split(' ');
  return type === 'Bearer' && Boolean(token);
}

Try / catch

try {
  await adminApi.call();
} catch (e) {
  if (e?.response?.status === 401 && e.message.includes('token不存在')) {
    await loginAsManager(); // 附上 Authorization: Bearer <token> 后重试
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/a0d89af0fd53cb73. Report an issue: GitHub.