-
Notifications
You must be signed in to change notification settings - Fork 235
refactor(auth): JJWT 라이브러리 업데이트 및 JWT 처리 로직 개선 #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- jjwt 라이브러리 버전 0.9.1 → 0.11.5로 업데이트 - `JwtTokenProvider` 내 키 생성 방식 개선 (Base64 디코딩 후 `Keys.hmacShaKeyFor` 사용) - `io.jsonwebtoken` 최신 방식 API로 전환 (`JwtParserBuilder` 활용) - `application.properties`에서 secret key 값 업데이트 - 종속성 추가 (`jjwt-api`, `jjwt-impl`, `jjwt-jackson`)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @theminjunchoi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request focuses on modernizing the JWT authentication logic by upgrading the JJWT library from version 0.9.1 to 0.11.5. This upgrade necessitated significant changes to how JWTs are created and validated, including adapting to the new modular structure of the library, updated API calls for signing tokens, and improved handling of the secret key. The changes aim to align the codebase with current best practices for JWT implementation using the latest JJWT features.
Highlights
- JJWT Library Upgrade: Upgraded the
io.jsonwebtoken:jjwtlibrary from version 0.9.1 to 0.11.5, adopting its new modular structure (jjwt-api,jjwt-impl,jjwt-jackson) and removing the no longer neededjavax.xml.bind:jaxb-apidependency. - Modernized Secret Key Handling: Refactored the
JwtTokenProviderto correctly handle the JWT secret key. Theapplication.propertiesnow stores a Base64 encoded 32-byte random key, which is then decoded and converted into ajava.security.Keyobject usingKeys.hmacShaKeyForfor signing and verification, aligning with the updatedsignWithmethod signature. - Improved Token Validation Flow: The
validateTokenmethod inJwtTokenProviderwas refactored from a public boolean-returning method to a private void method that throws aRuntimeExceptionupon invalid tokens. This method is now explicitly called withingetPayloadto ensure token validity before extracting claims, providing a more robust validation process. - API Adaptation: Updated JWT creation and parsing logic to use the new
Jwts.parserBuilder()andsignWith(Key key)methods introduced in JJWT 0.11.x.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request successfully updates the JJWT library to a newer version (0.11.5) and refactors the JWT handling logic in JwtTokenProvider to align with the new API, particularly the use of Keys.hmacShaKeyFor for key creation and Jwts.parserBuilder for parsing. The change to call validateToken internally within getPayload is a good improvement for ensuring token validity before extracting claims. The secret key format in application.properties has also been correctly updated. The changes are well-explained in the PR description. The only minor area for improvement identified is the generic exception thrown in validateToken, which could be more specific.
| claims.getBody().getExpiration(); | ||
| } catch (JwtException | IllegalArgumentException e) { | ||
| return false; | ||
| throw new RuntimeException("Invalid token"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing a generic RuntimeException here hides the specific cause of the token validation failure (e.g., expired token, invalid signature). It would be more informative to either throw a more specific exception or re-throw the original caught exception.
| throw new RuntimeException("Invalid token"); | |
| throw e; |
| claims.getBody().getExpiration(); | ||
| } catch (JwtException | IllegalArgumentException e) { | ||
| return false; | ||
| throw new RuntimeException("Invalid token"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing a generic RuntimeException here hides the specific cause of the token validation failure (e.g., expired token, invalid signature). It would be more informative to either throw a more specific exception or re-throw the original caught exception.
| throw new RuntimeException("Invalid token"); | |
| throw e; |
안녕하세요 우테코 7기 BE로 활동 중인 엠제이입니다.
혼자서 공부를 하다가 spring-learning-test에서 사용되던 jjwt 라이브러리가 너무 구 버전이라 현재와 달라진 점이 있다는 걸 발견했습니다.
pr을 올리면서도 생각을 해보니, 기존 코드도 충분히 인증/인가를 배우는데 문제가 안될 것도 같지만, 혹여나 도움이 될까 pr을 보냅니다.
일부러 merge 시켜주실 필요는 없고, 내용이 앞으로 스터디를 진행하실 분들에게 유의미하다고 생각이 드신다면 merge 해주시면 좋을 것 같아요.
1. jjwt 관련 라이브러리의 버전을 올렸습니다.
jjwt 라이브러리 0.10.0 버전부터 달라진 점 중 auth에 적용되는 변경점은 다음과 같습니다.
자세한 내용은 아래를 참고해주세요.
1.1 jwt-api / jjwt-imple / jjwt-jackson | gson 으로 모듈 나뉨
기존 build.gradle
수정 후 build.gradle
단일 JAR이 api, impl, jackson | gson으로 나눠져서 각각 build.gradle에 적어주었습니다.
javax.xml.bind:jaxb-api:2.3.1은 사용하는 곳이 없어서 제거해주었습니다.1.2 signWith의 파라미터값 변경
기존 버전
버전 up
기존에는 파라미터로 String 값을 받았던 반면, 버전 업 후에는 Key 값을 받도록 타입을 강제하고 있습니다.
이와 더불어 기존 코드의 application.properties를 보면 32byte(256bit)짜리 값을 Base64로 인코딩한 후의 값을 갖고 있던 게 아니라
JWT 토큰 자체를 들고 있어서 수정해주었습니다.
지금 application.properties에 들어가 있는 값은 32byte(256bit)짜리 랜덤 값을 Base64로 인코딩한 값입니다.
아래와 같이 뽑아서 사용하고 있습니다.
1.3 Keys 헬퍼 사용
1.2에서 signWith의 파라미터로 Key값이 필요해졌습니다.
그래서 application.properties에 있던 값을 우선 문자열로 불러오고,
256bit 짜리 바이트열로 바꾼다음, HMAC 전용 secretKey로 만들어주도록 수정했습니다.
Keys.hmacShaKeyFor를 사용함으로써 32byte 미만이면 에러를 반환하고,HS256 알고리즘을 자동으로 매핑 후,
SecretKeySpec을 생성할 수 있습니다.
JJWT에서 지원하는 서명 알고리즘은 HMAC 말고 RSA나 ECDSA 등도 있는 걸로 아는데,
학습용도 및 속도 측면에서는 충분할 것 같아서 HMAC을 선택했습니다.
ETC
기존에 만들어져있던
validateToken이 사용되고 있지 않아서 payLoad를 불러오는getPayLoad내부에서 호출해주도록 수정했습니다.Check