liujie
2026-09-09 39f6fca28e3f78abe48f08e474ec011abb990b36
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
44
45
46
47
48
49
50
51
52
53
package com.tourguide.security;
 
import com.tourguide.config.properties.JwtProperties;
import com.tourguide.modules.user.domain.ClientType;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;
 
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.UUID;
 
@Service
public class JwtTokenService {
    private final JwtProperties properties;
    private final Key signingKey;
 
    public JwtTokenService(JwtProperties properties) {
        this.properties = properties;
        this.signingKey = Keys.hmacShaKeyFor(properties.getSecret().getBytes(StandardCharsets.UTF_8));
    }
 
    /** Token 同时写入 clientType,服务端据此阻止后台端与小程序端交叉访问。 */
    public String createToken(Long userId, String username, String authority, ClientType clientType) {
        Date now = new Date();
        return Jwts.builder()
                .setIssuer(properties.getIssuer())
                .setSubject(String.valueOf(userId))
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(now)
                .setExpiration(new Date(now.getTime() + properties.getExpirationSeconds() * 1000L))
                .claim("username", username)
                .claim("role", authority)
                .claim("clientType", clientType.name())
                .signWith(signingKey)
                .compact();
    }
 
    public TokenPayload parse(String token) {
        Claims claims = Jwts.parserBuilder().setSigningKey(signingKey).requireIssuer(properties.getIssuer()).build()
                .parseClaimsJws(token).getBody();
        return new TokenPayload(
                Long.valueOf(claims.getSubject()),
                claims.get("username", String.class),
                claims.get("role", String.class),
                ClientType.valueOf(claims.get("clientType", String.class)),
                claims.getId());
    }
 
    public long getExpirationSeconds() { return properties.getExpirationSeconds(); }
}