seatonwan9
2025-08-28 e5d17ab1bc9e0779b325c53bf23d61ae4a15432e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.webmanage.service.impl;
 
import com.webmanage.service.TokenService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
 
@Service
public class TokenServiceImpl implements TokenService {
 
    private static final String IDEMPOTENCY_TOKEN_PREFIX = "idempotency:token:";
    private static final long DEFAULT_EXPIRE_SECONDS = 60 * 5; // 5分钟
 
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
 
    @Override
    public String generateToken(Long userId) {
        String token = UUID.randomUUID().toString().replace("-", "");
        String key = IDEMPOTENCY_TOKEN_PREFIX + token;
        // 值不重要,设置一个标记即可
        redisTemplate.opsForValue().set(key, userId == null ? 0L : userId, DEFAULT_EXPIRE_SECONDS, TimeUnit.SECONDS);
        return token;
    }
 
    @Override
    public boolean verifyAndConsume(String token) {
        if (token == null || token.isEmpty()) {
            return false;
        }
        String key = IDEMPOTENCY_TOKEN_PREFIX + token;
        Boolean existed = redisTemplate.hasKey(key);
        if (Boolean.TRUE.equals(existed)) {
            // 消费后删除,确保一次性
            redisTemplate.delete(key);
            return true;
        }
        return false;
    }
}