-
Notifications
You must be signed in to change notification settings - Fork 6
[USER] 유저 정보 API 개선 및 에러 페이지 추가, 권한 정책 반영 #65
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,7 +3,9 @@ | |||||||||||||||
| import io.github.petty.users.dto.EmailVerificationRequest; | ||||||||||||||||
| import io.github.petty.users.dto.RefreshTokenResponseDTO; | ||||||||||||||||
| import io.github.petty.users.dto.VerifyCodeRequest; | ||||||||||||||||
| import io.github.petty.users.entity.Users; | ||||||||||||||||
| import io.github.petty.users.jwt.JWTUtil; | ||||||||||||||||
| import io.github.petty.users.repository.UsersRepository; | ||||||||||||||||
| import io.github.petty.users.service.EmailService; | ||||||||||||||||
| import io.github.petty.users.service.RefreshTokenService; | ||||||||||||||||
| import io.github.petty.users.service.UserService; | ||||||||||||||||
|
|
@@ -29,13 +31,15 @@ public class UsersApiController { | |||||||||||||||
| private final EmailService emailService; | ||||||||||||||||
| private final RefreshTokenService refreshTokenService; | ||||||||||||||||
| private final CookieUtils cookieUtils; | ||||||||||||||||
| private final UsersRepository usersRepository; | ||||||||||||||||
|
|
||||||||||||||||
| public UsersApiController(JWTUtil jwtUtil, EmailService emailService, RefreshTokenService refreshTokenService, UserService userService, CookieUtils cookieUtils) { | ||||||||||||||||
| public UsersApiController(JWTUtil jwtUtil, EmailService emailService, RefreshTokenService refreshTokenService, UserService userService, CookieUtils cookieUtils, UsersRepository usersRepository) { | ||||||||||||||||
| this.jwtUtil = jwtUtil; | ||||||||||||||||
| this.userService = userService; | ||||||||||||||||
| this.emailService = emailService; | ||||||||||||||||
| this.refreshTokenService = refreshTokenService; | ||||||||||||||||
| this.cookieUtils = cookieUtils; | ||||||||||||||||
| this.usersRepository = usersRepository; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| @GetMapping("/users/me") | ||||||||||||||||
|
|
@@ -46,8 +50,11 @@ public ResponseEntity<Map<String, String>> getUserInfo() { | |||||||||||||||
| return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| Users user = usersRepository.findByUsername(auth.getName()); | ||||||||||||||||
|
|
||||||||||||||||
| Map<String, String> userInfo = new HashMap<>(); | ||||||||||||||||
| userInfo.put("username", auth.getName()); | ||||||||||||||||
| // TODO: 프론트엔드에서 username 키로 displayName을 사용 중(키 이름 정리 필요) | ||||||||||||||||
| userInfo.put("username", user.getDisplayName()); | ||||||||||||||||
|
Comment on lines
+56
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion API 응답 구조의 일관성을 개선하세요. TODO 코멘트에서 언급된 대로 키 이름의 불일치가 있습니다. 프론트엔드와의 계약을 명확히 하고 일관된 네이밍을 사용하는 것이 좋습니다. 다음과 같이 명확한 키 이름을 사용하는 것을 권장합니다: Map<String, String> userInfo = new HashMap<>();
-// TODO: 프론트엔드에서 username 키로 displayName을 사용 중(키 이름 정리 필요)
-userInfo.put("username", user.getDisplayName());
+userInfo.put("displayName", user.getDisplayName());
+userInfo.put("username", user.getUsername()); // 실제 사용자명이 필요한 경우또는 프론트엔드와 협의하여 API 계약을 명확히 정의하세요. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| userInfo.put("role", auth.getAuthorities().iterator().next().getAuthority()); | ||||||||||||||||
|
|
||||||||||||||||
| return ResponseEntity.ok(userInfo); | ||||||||||||||||
|
|
||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,204 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| <!DOCTYPE html> | ||||||||||||||||||||||||||||||||||||||||||||||
| <html lang="ko" xmlns:th="http://www.thymeleaf.org" | ||||||||||||||||||||||||||||||||||||||||||||||
| xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" | ||||||||||||||||||||||||||||||||||||||||||||||
| layout:decorate="~{layouts/defaultLayout}"> | ||||||||||||||||||||||||||||||||||||||||||||||
| <head> | ||||||||||||||||||||||||||||||||||||||||||||||
| <title>페이지를 찾을 수 없습니다</title> | ||||||||||||||||||||||||||||||||||||||||||||||
| <th:block layout:fragment="css"> | ||||||||||||||||||||||||||||||||||||||||||||||
| <style> | ||||||||||||||||||||||||||||||||||||||||||||||
| .error-container { | ||||||||||||||||||||||||||||||||||||||||||||||
| text-align: center; | ||||||||||||||||||||||||||||||||||||||||||||||
| padding: 50px 20px; | ||||||||||||||||||||||||||||||||||||||||||||||
| max-width: 600px; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin: 0 auto; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-code { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 8rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: bold; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin: 0; | ||||||||||||||||||||||||||||||||||||||||||||||
| background: linear-gradient(45deg, var(--accent-color), var(--point-color)); | ||||||||||||||||||||||||||||||||||||||||||||||
| -webkit-background-clip: text; | ||||||||||||||||||||||||||||||||||||||||||||||
| -webkit-text-fill-color: transparent; | ||||||||||||||||||||||||||||||||||||||||||||||
| background-clip: text; | ||||||||||||||||||||||||||||||||||||||||||||||
| text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-title { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 2rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| color: var(--text-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| margin: 20px 0; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: 600; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-message { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1.2rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| color: var(--secondary-text-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-bottom: 30px; | ||||||||||||||||||||||||||||||||||||||||||||||
| line-height: 1.6; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-actions { | ||||||||||||||||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||||||||||||||||
| gap: 15px; | ||||||||||||||||||||||||||||||||||||||||||||||
| justify-content: center; | ||||||||||||||||||||||||||||||||||||||||||||||
| flex-wrap: wrap; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-top: 40px; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn { | ||||||||||||||||||||||||||||||||||||||||||||||
| padding: 12px 24px; | ||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: 30px; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: 600; | ||||||||||||||||||||||||||||||||||||||||||||||
| text-decoration: none; | ||||||||||||||||||||||||||||||||||||||||||||||
| transition: all 0.3s ease; | ||||||||||||||||||||||||||||||||||||||||||||||
| cursor: pointer; | ||||||||||||||||||||||||||||||||||||||||||||||
| border: none; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-family: inherit; | ||||||||||||||||||||||||||||||||||||||||||||||
| display: inline-block; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn-primary { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--accent-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| color: white; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn-primary:hover { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--button-hover-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| transform: translateY(-2px); | ||||||||||||||||||||||||||||||||||||||||||||||
| box-shadow: var(--box-shadow-cute); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn-secondary { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--point-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| color: white; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn-secondary:hover { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: #8fa97a; | ||||||||||||||||||||||||||||||||||||||||||||||
| transform: translateY(-2px); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .cute-illustration { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 4rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin: 30px 0; | ||||||||||||||||||||||||||||||||||||||||||||||
| opacity: 0.8; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .search-suggestion { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--card-bg-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: var(--border-radius-lg); | ||||||||||||||||||||||||||||||||||||||||||||||
| padding: 25px; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin: 30px 0; | ||||||||||||||||||||||||||||||||||||||||||||||
| box-shadow: var(--box-shadow-light); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .search-suggestion h3 { | ||||||||||||||||||||||||||||||||||||||||||||||
| color: var(--accent-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-bottom: 15px; | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1.3rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-links { | ||||||||||||||||||||||||||||||||||||||||||||||
| display: grid; | ||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | ||||||||||||||||||||||||||||||||||||||||||||||
| gap: 15px; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-top: 20px; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-link { | ||||||||||||||||||||||||||||||||||||||||||||||
| display: block; | ||||||||||||||||||||||||||||||||||||||||||||||
| padding: 15px; | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: rgba(158, 188, 138, 0.1); | ||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: var(--border-radius-md); | ||||||||||||||||||||||||||||||||||||||||||||||
| text-decoration: none; | ||||||||||||||||||||||||||||||||||||||||||||||
| color: var(--text-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| transition: all 0.3s ease; | ||||||||||||||||||||||||||||||||||||||||||||||
| border: 2px solid transparent; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-link:hover { | ||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--point-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| color: white; | ||||||||||||||||||||||||||||||||||||||||||||||
| transform: translateY(-2px); | ||||||||||||||||||||||||||||||||||||||||||||||
| border-color: var(--accent-color); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-link .icon { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1.5rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-bottom: 8px; | ||||||||||||||||||||||||||||||||||||||||||||||
| display: block; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-link .title { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: 600; | ||||||||||||||||||||||||||||||||||||||||||||||
| margin-bottom: 5px; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .quick-link .desc { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 0.9rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| opacity: 0.8; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @media (max-width: 768px) { | ||||||||||||||||||||||||||||||||||||||||||||||
| .error-code { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 6rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-title { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1.5rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-message { | ||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 1rem; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .error-actions { | ||||||||||||||||||||||||||||||||||||||||||||||
| flex-direction: column; | ||||||||||||||||||||||||||||||||||||||||||||||
| align-items: center; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| .btn { | ||||||||||||||||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||||||||||||||||
| max-width: 250px; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| </style> | ||||||||||||||||||||||||||||||||||||||||||||||
| </th:block> | ||||||||||||||||||||||||||||||||||||||||||||||
| </head> | ||||||||||||||||||||||||||||||||||||||||||||||
| <body> | ||||||||||||||||||||||||||||||||||||||||||||||
| <th:block layout:fragment="content"> | ||||||||||||||||||||||||||||||||||||||||||||||
| <main> | ||||||||||||||||||||||||||||||||||||||||||||||
| <div class="error-container"> | ||||||||||||||||||||||||||||||||||||||||||||||
| <div class="error-code">404</div> | ||||||||||||||||||||||||||||||||||||||||||||||
| <h1 class="error-title">페이지를 찾을 수 없습니다</h1> | ||||||||||||||||||||||||||||||||||||||||||||||
| <div class="cute-illustration">🐕🦺 🔍</div> | ||||||||||||||||||||||||||||||||||||||||||||||
| <p class="error-message"> | ||||||||||||||||||||||||||||||||||||||||||||||
| 앗! 우리 반려동물이 길을 잃었나봐요.<br> | ||||||||||||||||||||||||||||||||||||||||||||||
| 요청하신 페이지를 찾을 수 없습니다. | ||||||||||||||||||||||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+173
to
+180
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 사용자 경험을 개선하기 위한 네비게이션 요소가 누락되었습니다. 에러 메시지는 친근하고 적절하지만, 사용자가 메인 페이지나 이전 페이지로 돌아갈 수 있는 버튼이나 링크가 없습니다. CSS에는 다음과 같이 네비게이션 요소를 추가하는 것을 권장합니다: <p class="error-message">
앗! 우리 반려동물이 길을 잃었나봐요.<br>
요청하신 페이지를 찾을 수 없습니다.
</p>
+
+ <div class="error-actions">
+ <a href="/" class="btn btn-primary">홈으로 돌아가기</a>
+ <button onclick="history.back()" class="btn btn-secondary">이전 페이지</button>
+ </div>
</div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||
| </main> | ||||||||||||||||||||||||||||||||||||||||||||||
| </th:block> | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| <th:block layout:fragment="script"> | ||||||||||||||||||||||||||||||||||||||||||||||
| <script> | ||||||||||||||||||||||||||||||||||||||||||||||
| // 페이지 로드 시 귀여운 애니메이션 효과 | ||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('DOMContentLoaded', function() { | ||||||||||||||||||||||||||||||||||||||||||||||
| const illustration = document.querySelector('.cute-illustration'); | ||||||||||||||||||||||||||||||||||||||||||||||
| if (illustration) { | ||||||||||||||||||||||||||||||||||||||||||||||
| illustration.style.opacity = '0'; | ||||||||||||||||||||||||||||||||||||||||||||||
| illustration.style.transform = 'scale(0.8)'; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||||
| illustration.style.transition = 'all 0.5s ease'; | ||||||||||||||||||||||||||||||||||||||||||||||
| illustration.style.opacity = '0.8'; | ||||||||||||||||||||||||||||||||||||||||||||||
| illustration.style.transform = 'scale(1)'; | ||||||||||||||||||||||||||||||||||||||||||||||
| }, 200); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||
| </th:block> | ||||||||||||||||||||||||||||||||||||||||||||||
| </body> | ||||||||||||||||||||||||||||||||||||||||||||||
| </html> | ||||||||||||||||||||||||||||||||||||||||||||||
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.
사용자 조회 시 null 체크가 필요합니다.
usersRepository.findByUsername()이 null을 반환할 수 있으므로 적절한 처리가 필요합니다.📝 Committable suggestion
🤖 Prompt for AI Agents