요새 저번에 했던 프로젝트 코드를 다시 Spring으로 작성해보고 있다. 저번 프로젝트에서 JWT를 써서 로그인을 구현했는데, 이에 대한 포스팅이 없어서 이번에 정리해보려고 한다. 🙂
해당 블로그를 참고했다.
https://shinsunyoung.tistory.com/110
JWT는 JSON Web Token의 약자이다. 인증을 위한 정보를 따로 저장소 없이 전자 서명을 이용해 확인하는 방법이라고 볼 수 있다.
그럼 이 웹 토큰을 언제 사용할까? 내가 프로젝트를 할 때 사용한 방식은 로그인 시에 웹 토큰을 서버에서 만들어 쿠키에 저장해주고, 클라이언트에서 쿠키에 있는 토큰이 유효한 토큰인지 검사하게 된다.
JWT의 구성은 다음과 같이 이루어져있다.
JWT를 사용하는 이유는, 별도의 인증 저장소가 필요없다는 것이다. 이는 유저의 세션을 서버에서 유지할 필요가 없어지고, 서버의 자원을 아낄 수 있다. 또한 JWT를 사용하면 정보를 교환할 때 안정성있게 사용될 수 있다. 정보가 전자 서명 되어있기 때문에 정보가 조작되어있는지, 유효한 토큰인지 검증할 수 있기 때문이다.
jwt를 사용하기 위해 의존성을 추가해야 한다. 다음 코드를 build.gradle에 추가해준다.
implementation 'io.jsonwebtoken:jjwt:0.9.1'
다음으로 토큰을 생성하는 코드를 작성한다.
private String makeJwtToken(String userId, String nickname) {
Date now = new Date();
return Jwts.builder()
.setHeaderParam(Header.TYPE, Header.JWT_TYPE)
.setIssuedAt(now)
.claim("userId", userId)
.claim("nickname", nickname)
.signWith(SignatureAlgorithm.HS256, JWT_SECRET_KEY)
.compact();
}
마지막으로, compact()를 통해 토큰을 생성해준다.
클라이언트에게 알려야 하므로, 쿠키에 토큰을 설정해준다.
@PostMapping("/login")
@ResponseBody
public UserLoginResponse login(@RequestBody UserInfo userInfo, HttpServletResponse response){
UserLoginResponse resp = new UserLoginResponse();
String userId = userInfo.getUserId();
String password = userInfo.getPassword();
String userToken = userService.getUserToken(userId, password);
Cookie cookie = new Cookie("token", userToken);
cookie.setMaxAge(1000 * 60 * 60 * 24 * 7);
cookie.setHttpOnly(true);
resp.setUserId(userId);
response.addCookie(cookie);
return resp;
}
유저의 아이디와 비밀번호를 입력받으면 유효한 유저인지, 비밀번호가 알맞은지 검사한다. 모든 케이스를 통과하면 토큰을 생성하게 되고, 이 토큰을 반환 받는다.
다음으로 token이라는 이름을 가지고 생성한 토큰을 value로 가지는 쿠키를 생성한다.
body에 id와 password를 넣어서 전송하면,
다음과 같이 쿠키가 설정된 모습을 확인할 수 있다. 이전 프로젝트에서 refresh token이랑 access token을 설정했는데, 여기까지 할 수 있으려나 모르겠다..^^;