[개발환경]
M2 OSX Ventura 13.2.1
VS Code
SpringBoot 3.0.2
OpenJDK 17
Gradle 7.6
[Docker]
- mysql:latest
들어가며
Spring Session과 JWT는 둘 다 스프링 부트 애플리케이션에서 인증과 세션 관리를 위해 사용될 수 있지만, 서로 다른 방식으로 작동한다.
앞선 포스트에서 Spring Session에 대해서 설명하고 직접 구현해 보았다.
2023.03.08 - [DEV/SpringBoot] - [SpringBoot3] 로그인 페이지 실습 1
JWT는 서버와 클라이언트 간의 인증에 사용되며, 클라이언트에서 토큰을 생성하고 서버에서 검증한다. JWT는 사용자 정보와 권한 정보를 포함할 수 있으며, 서버 측에서 세션을 저장하거나 관리하지 않는다. JWT는 토큰을 사용하기 때문에, 서버와 클라이언트 간의 통신에서 매번 인증 정보를 전송해야 할 필요 없이 토큰만을 전송하여 인증할 수 있다.
JWT를 이용한 인증 및 인가 구현
'jjwt' 라이브러리를 이용하여 JWT 토큰을 생성하고 검증할 수 있다.
먼저, 의존성을 추가한다.[build.gradle]
dependencies{
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt'
}
JWT 토큰을 생성하고 검증하는 'JwtUtils' 클래스를 작성한다. [JwtUtils.java]
@Component
public class JwtUtils {
private final String secret = "secret"; // JWT secret key
private final long validityInMilliseconds = 3600000; // 1 hour
public String createToken(String username) {
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setSubject(username)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public String getUsernameFromToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
}
로그인 화면과 로그인 처리를 담당할 'LoginController' 클래스 작성한다. [LoginController.java]
@RestController
@RequestMapping("/auth")
public class LoginController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.createToken(loginRequest.getUsername());
return ResponseEntity.ok(new JwtResponse(jwt));
}
}
[LoginRequest.java]
@Getter
@Setter
public class LoginRequest {
private String username;
private String password;
}
[JwtResponse.java]
@Getter
public class JwtResponse {
private String token;
public JwtResponse(String token) {
this.token = token;
}
}
인증된 사용자만 접근을 허용할 /home 경로로 이동시킬 'HomeController.java'
@RestController
@RequestMapping("/api")
public class HomeController {
@GetMapping("/user")
@PreAuthorize("hasRole('USER')")
public String userAccess() {
return "User Content.";
인증 이후 토큰을 검증하는 방법, 안전하게 보관하는 방법에 대해서 다음 포스트에서 다룬다.
참고
점프 투 스프링부트(https://wikidocs.net/book/7601)
'DEV > SpringBoot' 카테고리의 다른 글
[SpringBoot3] 로그인 페이지 실습 1 (0) | 2023.03.08 |
---|---|
[SpringBoot3] Gradle 빌드 오류(Could not build action using Gradle distribution) (3) | 2023.03.01 |
[SpringBoot 3] MySql 연동하기 (0) | 2023.02.22 |
[SpringBoot3] Springboot 3.X에 Swagger 적용하기 (0) | 2023.02.15 |