yikart/AiToEarn · error · UnauthorizedException
需要管理员权限2
Error message
需要管理员权限2
What it means
The catch-all of ManagerGuard.canActivate: any failure during jwtService.verifyAsync (expired token, bad signature, malformed token) is swallowed and rethrown as UnauthorizedException '需要管理员权限2'. This masks the underlying JWT error, so any invalid manager token produces this message — including the inner '需要管理员权限1' being caught and replaced.
Source
Thrown at project/aitoearn-electron/server/src/auth/manager.guard.ts:62
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;
}
private extractTokenFromHeader(request: Request): string | undefined {
const [type, token] = request.headers.authorization?.split(' ') ?? [];
return type === 'Bearer' ? token : undefined;
}
}
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Re-login as manager to get a fresh valid token.
- Refactor the catch to rethrow the inner UnauthorizedException instead of masking it.
- Log the original error in the catch block to see whether it was expiry, signature, or the isManager check.
- Confirm AUTH_SECRET env var is set and identical on all instances.
Example fix
// before
} catch {
throw new UnauthorizedException('需要管理员权限2');
}
// after
} catch (e) {
if (e instanceof UnauthorizedException) throw e;
throw new UnauthorizedException('需要管理员权限2');
} Defensive patterns
Strategy: try-catch
Validate before calling
function tokenLooksValid(token) {
const t = token.replace(/^Bearer\s+/, '');
if (t.split('.').length !== 3) return false;
const payload = JSON.parse(atob(t.split('.')[1]));
return payload.exp * 1000 > Date.now() && payload.isManager === true;
} Try / catch
try {
await adminApi.call(managerToken);
} catch (e) {
if (e?.response?.status === 401 && e.message.includes('需要管理员权限2')) {
await reloginAsManager(); // verify 失败:过期/签名错误/格式错误,重新登录
} else throw e;
} Prevention
- Since the guard masks the real cause ('权限2'), check token exp and signature client-side before calling.
- Keep AUTH_SECRET stable across deploys or support dual-secret grace verification.
- Re-login when any admin 401 occurs — retrying the same token will fail identically.
- Report/fix the guard to rethrow inner UnauthorizedException so '权限1' is distinguishable.
When it happens
Trigger: verifyAsync throws — expired JWT, wrong AUTH_SECRET, malformed token, or the inner UnauthorizedException from the isManager check being caught by this catch block.
Common situations: Expired manager session; secret mismatch after deploy; debugging confusion because the '权限1' message never surfaces and always becomes '权限2'.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/8e0adbee8127d49c.
Report an issue: GitHub.