# 令牌撤销中的竞态条件允许重复使用过期令牌

- **ID:** `security/race-condition-in-token-revocation`
- **领域:** security
- **类别:** runtime_error
- **错误码:** `AUTH_RACE_002`
- **验证级别:** ai_generated
- **修复率:** 78%

## 根因

当令牌被撤销但并发请求在撤销完全提交到数据库之前验证它时，会发生竞态条件，允许重复使用过期令牌。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| JWT 0.12.0 | active | — | — |
| OAuth2 2.0 | active | — | — |
| Redis 7.2 | active | — | — |

## 解决方案

1. ```
   Use a distributed lock (e.g., Redis Redlock) around the revocation and validation operations to ensure atomicity. Example in Node.js:
const lock = await redisClient.acquireLock('token_revoke_lock', 5000);
try {
    await revokeTokenInDB(tokenId);
    // Validation will now see the revoked state
} finally {
    await lock.release();
}
   ```
2. ```
   Implement a short blacklist (5-10 seconds) in memory (e.g., Guava Cache) for recently revoked tokens before checking the database, reducing the race window.
   ```

## 无效尝试

- **Use a simple cache like Memcached with a short TTL to store revoked tokens** — Caching with TTL can expire before the revocation is processed, still allowing reuse; also, cache inconsistency across nodes worsens the race. (85% 失败率)
- **Add a small sleep() before validation after revocation** — Sleeping is non-deterministic and doesn't guarantee atomicity; it also degrades performance. (90% 失败率)
