서론.
해당 프로젝트에서는 오로지
카카오 소셜 로그인
만 사용한다. ( ID/PW 사용안함! )
이전 포스팅✅에서는 JWT 를 사용하기 전에 미리 알아두면 좋은 지식에 대해 이야기해보았다. 이어서 지식을 바탕으로 JWT 를 직접 생성해 응답 헤더에 넣어보자.
기본 의존성 :
Spring Web
Spring boot DevTools
Lombok
Spring Security
MySQL Driver
spring Data JPA
추가한 의존성 :
jackson-databind
jackson-datatype-jsr310
java-jwt
경로에 jwt
라는 패키지를 만들고 그 안에 JwtProperties
라는 인터페이스를 만든다.
public interface JwtProperties { //(1)
String SECRET = "{}"; //(2)
int EXPIRATION_TIME = 864000000; //(3)
String TOKEN_PREFIX = "Bearer "; //(4)
String HEADER_STRING = "Authorization"; //(5)
}
public static final
이 붙는다.Signatuer
를 해싱할 때 사용되는 비밀 키이다. 영어로 원하는 단어를 적어주면 된다.Bearer
뒤에 한 칸 공백을 넣어줘야 한다.Authorization
이라는 항목에 토큰을 넣어줄 것이다.
이전 포스팅에서 수정한 api에 로직을 추가해 준다.
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
// 프론트에서 인가코드 받아오는 url
@GetMapping("/oauth/token")
public ResponseEntity getLogin(@RequestParam("code") String code) { //(1)
// 넘어온 인가 코드를 통해 access_token 발급
OauthToken oauthToken = userService.getAccessToken(code);
//(2)
// 발급 받은 accessToken 으로 카카오 회원 정보 DB 저장 후 JWT 를 생성
String jwtToken = userService.SaveUserAndGetToken(oauthToken.getAccess_token());
//(3)
HttpHeaders headers = new HttpHeaders();
headers.add(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + jwtToken);
//(4)
return ResponseEntity.ok().headers(headers).body("success");
}
}
ResponseEntity
로 바꿔준다.UserService
의 기존 SaveUser
메소드를 수정한다.(👇아래 참고)Authorization
이라는 항목에 JWT 를 넣어준다.JWT
가 담긴 헤더와 200 ok
스테이터스 값, "success"
라는 바디값을 ResponseEntity
에 담아 프론트 측에 전달한다.
@Service
public class UserService {
@Autowired
UserRepository userRepository;
. . . (생략)
public String saveUserAndGetToken(String token) { //(1)
KakaoProfile profile = findProfile(token);
User user = userRepository.findByKakaoEmail(profile.getKakao_account().getEmail());
if(user == null) {
user = User.builder()
.kakaoId(profile.getId())
.kakaoProfileImg(profile.getKakao_account().getProfile().getProfile_image_url())
.kakaoNickname(profile.getKakao_account().getProfile().getNickname())
.kakaoEmail(profile.getKakao_account().getEmail())
.userRole("ROLE_USER").build();
userRepository.save(user);
}
return createToken(user); //(2)
}
public String createToken(User user) { //(2-1)
//(2-2)
String jwtToken = JWT.create()
//(2-3)
.withSubject(user.getKakaoEmail())
.withExpiresAt(new Date(System.currentTimeMillis()+ JwtProperties.EXPIRATION_TIME))
//(2-4)
.withClaim("id", user.getUserCode())
.withClaim("nickname", user.getKakaoNickname())
//(2-5)
.sign(Algorithm.HMAC512(JwtProperties.SECRET));
return jwtToken; //(2-6)
}
}
기존에 있던 saveUser
메소드의 이름을 saveUserAndGetToken
으로 바꾸고 리턴 타입을 String
으로 바꾼다.
createToken()
메소드를 이용해 String
형의 JWT
를 반환한다.
1. 파라미터로 User
객체를 받고 리턴 타입이 String
인 createToken()
메소드를 만든다.
java-jwt
라이브러리를 사용하기 때문에 jjwt
라이브러리와 문법이 다르므로 주의한다.Payload
에 들어갈 등록된 클레임
을 설정한다.sub
는 자유롭게 지정한다. (별로 중요하지 않다)exp
는 앞서 만든 JwtProperties
의 만료 시간 필드를 불러와 위와 같이 작성한다.Payload
에 들어갈 개인 클레임
을 설정한다..withClaim(이름, 내용)
형태로 작성한다. 사용자를 식별할 수 있는 값과, 따로 추가하고 싶은 값을 자유롭게 넣는다.Signature
를 설정한다. 위와 같이 알고리즘을 명시하고 앞서 만든 JwtProperties
의 비밀 키 필드를 불러와 넣어준다.도움 받은 영상 :
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9
마치며.
여기까지 잘 따라왔다면 응답 헤더에 JWT가 잘 담겨져있을 것이다.
다음은 JWT 를 요청 헤더에 담아 보내왔을 때 토큰의 유효성을 검사하고 인증된 사용자의 정보를 불러오는 법에 대해 포스팅해 보겠다. 많관부많관부~🥳💖