JWT (JSON Web Token) = stateless authentication — server không lưu session, verify bằng signature.
Flow:
1. POST /login → server verify → ký JWT
2. Client gửi: "Authorization: Bearer <token>"
3. Server verify signature → extract claims → authorizeSpring Security 6 Resource Server (JWT):
@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
.authorizeHttpRequests(a -> a.anyRequest().authenticated())
.oauth2ResourceServer(o -> o.jwt(j ->
j.jwkSetUri("https://auth.example.com/.well-known/jwks.json")
))
.build();
}Lưu ý quan trọng:
- JWT không revocable (trừ khi dùng blocklist).
- Access token: TTL ngắn (15min-1h). Refresh token: TTL dài, lưu DB để revoke.
- Không đặt sensitive data trong payload (JWT chỉ sign, không encrypt — ai cũng decode được bằng base64).
JWT (JSON Web Token) = stateless authentication — the server stores no session, verifies via signature.
Flow:
1. POST /login → server verifies → signs JWT
2. Client sends: "Authorization: Bearer <token>"
3. Server verifies signature → extracts claims → authorisesSpring Security 6 Resource Server (JWT):
@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
.authorizeHttpRequests(a -> a.anyRequest().authenticated())
.oauth2ResourceServer(o -> o.jwt(j ->
j.jwkSetUri("https://auth.example.com/.well-known/jwks.json")
))
.build();
}Important notes:
- JWTs are not revocable (unless you maintain a blocklist).
- Access token: short TTL (15min–1h). Refresh token: long TTL, stored in DB for revocation.
- Do not put sensitive data in the payload (JWT is signed, not encrypted — anyone can decode with base64).