JWT๋ ์ธ ๊ฐ์ง ๋ถ๋ถ์ผ๋ก ์ด๋ฃจ์ด์ ธ์๋ค.
์ฌ์ฉ์๋ ์์ ์ ์๊ฒฉ ์ฆ๋ช (์: ์ฌ์ฉ์๋ช ๊ณผ ๋น๋ฐ๋ฒํธ)์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ ์์ฒญ์ ๋ณด๋ธ๋ค.
// HTTP POST ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋
// "/login" ์๋ํฌ์ธํธ์ ๋ก๊ทธ์ธ ์์ฒญ์ด ์ค๋ฉด ์ด ๋ฉ์๋๊ฐ ํธ์ถ๋จ
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
// ์ฌ์ฉ์๊ฐ ์
๋ ฅํ username๊ณผ password๋ก Authentication ๊ฐ์ฒด๋ฅผ ์์ฑ
// ์ด ๊ฐ์ฒด๋ Spring Security์์ ์ ๊ณตํ๋ ์ธ์ฆ ๋ฉ์ปค๋์ฆ์ด ์ฌ์ฉํจ
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(), // ์ฌ์ฉ์ ์
๋ ฅ username
loginRequest.getPassword() // ์ฌ์ฉ์ ์
๋ ฅ password
)
);
// ์ธ์ฆ๋ Authentication ๊ฐ์ฒด๋ฅผ SecurityContextHolder์ ์ค์
// SecurityContextHolder๋ ํ์ฌ ์ฌ์ฉ์์ ๋ณด์ ์ปจํ
์คํธ๋ฅผ ๋ณด๊ดํ๋๋ฐ ์ฌ์ฉ๋จ
SecurityContextHolder.getContext().setAuthentication(authentication);
// JWT ํ ํฐ ์์ฑ์ ์ํด tokenProvider์ generateToken ๋ฉ์๋๋ฅผ ํธ์ถ,
// ์ธ์ฆ๋ ์ฌ์ฉ์์ ๋ํ JWT๋ฅผ ์์ฑ
String jwt = tokenProvider.generateToken(authentication);
// ์์ฑ๋ JWT๋ฅผ ์๋ต์ผ๋ก ๋ฐํ
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
์๋ฒ๋ ์ฌ์ฉ์์ ์๊ฒฉ ์ฆ๋ช ์ ํ์ธํ๊ณ , ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก JWT๋ฅผ ์์ฑํ๋ค. JWT ์์ฑ์ ์ผ๋ฐ์ ์ผ๋ก ์๋ฒ์ ๋น๋ฐ ํค(secret key)๋ฅผ์ฌ์ฉํ์ฌ ์ด๋ฃจ์ด์ง๋ค.
// JWT ํ ํฐ์ ์์ฑํ๋ ๋ฉ์๋
public String generateToken(Authentication authentication) {
// Authentication ๊ฐ์ฒด์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ด
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
// ํ์ฌ ์๊ฐ์ ๊ฐ์ ธ์ค๊ณ ,
Date now = new Date();
// ํ ํฐ์ ์ ํจ๊ธฐ๊ฐ์ ์ค์
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
// JWT ๋น๋๋ฅผ ์ฌ์ฉํด JWT ํ ํฐ์ ์์ฑ
// Subject์๋ ์ฌ์ฉ์ ID๋ฅผ, ๋ฐํ์๊ฐ๊ณผ ๋ง๋ฃ์๊ฐ์ ์ค์
// ์ดํ ์๋ฒ์ ๋น๋ฐ ํค๋ฅผ ์ฌ์ฉํด ์๋ช
ํจ
return Jwts.builder()
.setSubject(Long.toString(userPrincipal.getId())) // ์ฌ์ฉ์ ID
.setIssuedAt(new Date()) // ๋ฐํ ์๊ฐ
.setExpiration(expiryDate) // ๋ง๋ฃ ์๊ฐ
.signWith(SignatureAlgorithm.HS512, jwtSecret) // ์๋ช
.compact();
}
// ์์ฑ๋ JWT๋ฅผ ๋ฐํํ๋ ๊ณผ์
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
// ... ์๋ต ...
// ์์ฑ๋ JWT๋ฅผ HTTP ์๋ต ๋ฐ๋์ ๋ด์ ๋ฐํ
// JwtAuthenticationResponse๋ JWT๋ฅผ ๋ด๋ ํด๋์ค
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
์์ฑ๋ JWT๋ ์ฌ์ฉ์์๊ฒ ๋ฐํ๋๋ค. ์ด ํ ํฐ์ ์ผ๋ฐ์ ์ผ๋ก HTTP ์๋ต ํค๋ ํน์ ๋ฐ๋์ ํฌํจ๋์ด ์ ๋ฌ๋๋ค. ์ด ๊ฒฝ์ฐ ์๋ฒ์ ์๋ต์ application/json ํ์์ผ๋ก, ๋ค์๊ณผ ๊ฐ๋ค.
{
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"tokenType": "Bearer"
}
//"accessToken"์ ๋ฐ๊ธ๋ JWT, "tokenType"์ ์ด ํ ํฐ์ด Bearer ํ์
์์ ๋ปํจ
์ฌ์ฉ์๋ ์ด๋ ๊ฒ ๋ฐํ๋ JWT๋ฅผ ๊ฐ์ง๊ณ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค ์ด ํ ํฐ์ Authorization ํค๋์ ํฌํจ์ํจ๋ค. ์๋ฒ๋ ์ด ํ ํฐ์ ํด๋ ํ์ฌ ์ฌ์ฉ์๋ฅผ ์ธ์ฆํ ์ ์๋ค.
JWT๋ ์ ๋ณด๋ฅผ ์์ ํ๊ฒ ์ ์กํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง๋ง, ์ฌ์ ํ ๋ช ๊ฐ์ง ์ฃผ์ ์ฌํญ์ด ์๋ค.