
--- src/main/java/kr/co/takensoft/ai/system/auth/dao/AuthDAO.java
+++ src/main/java/kr/co/takensoft/ai/system/auth/dao/AuthDAO.java
... | ... | @@ -24,4 +24,12 @@ |
24 | 24 |
* 사용자 회원 가입 |
25 | 25 |
*/ |
26 | 26 |
int memberRegister(MemberVO memberVO) throws Exception; |
27 |
+ |
|
28 |
+ /** |
|
29 |
+ * @param memberId 사용자 아이디 |
|
30 |
+ * @return 사용자 정보 |
|
31 |
+ * |
|
32 |
+ * 사용자 정보 개인 정보 조회 |
|
33 |
+ */ |
|
34 |
+ MemberVO findMemberInfo(String memberId) throws Exception; |
|
27 | 35 |
} |
+++ src/main/java/kr/co/takensoft/ai/system/auth/dao/RefreshDAO.java
... | ... | @@ -0,0 +1,35 @@ |
1 | +package kr.co.takensoft.ai.system.auth.dao; | |
2 | + | |
3 | +import kr.co.takensoft.ai.system.auth.dto.RefreshTokenDTO; | |
4 | +import org.apache.ibatis.annotations.Param; | |
5 | + | |
6 | +/* | |
7 | + * @author : 박민혁 | |
8 | + * @since : 2025.04.18 | |
9 | + * @modification | |
10 | + * since | author | description | |
11 | + * 2025.04.18 | 박민혁 | 최초 등록 | |
12 | + * | |
13 | + * 리프레시 토큰 관련 DAO | |
14 | + */ | |
15 | +public interface RefreshDAO { | |
16 | + /** | |
17 | + * @param refreshTokenDTO 리프레시 토큰과 관련된 정보 | |
18 | + * | |
19 | + * 리프레시 토큰 저장 혹은 갱신 | |
20 | + */ | |
21 | + void saveRefreshToken(RefreshTokenDTO refreshTokenDTO); | |
22 | + | |
23 | + /** | |
24 | + * @param memberId 사용자 아이디 | |
25 | + * @return 리프레시 토큰 정보 | |
26 | + * 유저 아이디로 리프레시 토큰을 받아오기 | |
27 | + */ | |
28 | + String getRefreshTokenByUserId(String memberId); | |
29 | + | |
30 | + /** | |
31 | + * @param memberId 사용자 아이디 | |
32 | + * 리프레시 토큰 삭제 | |
33 | + */ | |
34 | + void deleteRefreshToken(String memberId); | |
35 | +} |
+++ src/main/java/kr/co/takensoft/ai/system/auth/dto/RefreshTokenDTO.java
... | ... | @@ -0,0 +1,29 @@ |
1 | +package kr.co.takensoft.ai.system.auth.dto; | |
2 | + | |
3 | +import jakarta.validation.constraints.NotNull; | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +/** | |
8 | + * @author : 박민혁 | |
9 | + * @since : 2025.07.09 | |
10 | + * @modification | |
11 | + * since | author | description | |
12 | + * 2025.07.09 | 박민혁 | 최초 등록 | |
13 | + * | |
14 | + * 리프레시 액세스 토큰 관련 DTO | |
15 | + */ | |
16 | +@Setter | |
17 | +@Getter | |
18 | +public class RefreshTokenDTO { | |
19 | + @NotNull | |
20 | + private String memberId; // 사용자 아이디 | |
21 | + @NotNull | |
22 | + private String refreshToken; // 리프레시 토큰 내용 | |
23 | + | |
24 | + public RefreshTokenDTO(String memberId, String refreshToken) { | |
25 | + this.memberId = memberId; | |
26 | + this.refreshToken = refreshToken; | |
27 | + } | |
28 | + | |
29 | +} |
+++ src/main/java/kr/co/takensoft/ai/system/auth/dto/TokenDTO.java
... | ... | @@ -0,0 +1,31 @@ |
1 | +package kr.co.takensoft.ai.system.auth.dto; | |
2 | + | |
3 | +import jakarta.validation.constraints.NotNull; | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +/** | |
8 | + * @author : 박민혁 | |
9 | + * @since : 2025.07.09 | |
10 | + * @modification | |
11 | + * since | author | description | |
12 | + * 2025.07.09 | 박민혁 | 최초 등록 | |
13 | + * | |
14 | + * 액세스 토큰 관련 DTO | |
15 | + */ | |
16 | +@Setter | |
17 | +@Getter | |
18 | +public class TokenDTO { | |
19 | + @NotNull | |
20 | + private String loginId; // 로그인 아이디 | |
21 | + @NotNull | |
22 | + private String memberId; // 사용자 아이디 | |
23 | + @NotNull | |
24 | + private String memberName; // 사용자 이름 | |
25 | + | |
26 | + public TokenDTO(String loginId, String memberId, String memberName) { | |
27 | + this.loginId = loginId; | |
28 | + this.memberId = memberId; | |
29 | + this.memberName = memberName; | |
30 | + } | |
31 | +} |
--- src/main/java/kr/co/takensoft/ai/system/auth/service/AuthService.java
+++ src/main/java/kr/co/takensoft/ai/system/auth/service/AuthService.java
... | ... | @@ -1,6 +1,9 @@ |
1 | 1 |
package kr.co.takensoft.ai.system.auth.service; |
2 | 2 |
|
3 |
+import kr.co.takensoft.ai.system.auth.dto.LoginDTO; |
|
3 | 4 |
import kr.co.takensoft.ai.system.auth.vo.MemberVO; |
5 |
+ |
|
6 |
+import java.util.Map; |
|
4 | 7 |
|
5 | 8 |
/* |
6 | 9 |
* @author : 박민혁 |
... | ... | @@ -13,11 +16,27 @@ |
13 | 16 |
*/ |
14 | 17 |
public interface AuthService { |
15 | 18 |
/** |
16 |
- * @param member 사용자 정보 |
|
19 |
+ * @param memberVO 사용자 정보 |
|
17 | 20 |
* @return 등록 성공 여부 |
18 | 21 |
* |
19 | 22 |
* 사용자 회원가입 |
20 | 23 |
*/ |
21 | 24 |
int memberRegister(MemberVO memberVO); |
22 | 25 |
|
26 |
+ /** |
|
27 |
+ * @param LoginDTO 로그인 정보 |
|
28 |
+ * @return 액세스 토큰과 리프레시 토큰 |
|
29 |
+ * |
|
30 |
+ * 사용자 회원가입 |
|
31 |
+ */ |
|
32 |
+ Map<String, String> memberLogin(LoginDTO loginDTO) throws Exception; |
|
33 |
+ |
|
34 |
+ /** |
|
35 |
+ * @param memberId 사용자 아이디 |
|
36 |
+ * @return 사용자 정보 |
|
37 |
+ * |
|
38 |
+ * 사용자 정보 개인 정보 조회 |
|
39 |
+ */ |
|
40 |
+ MemberVO findMemberInfo(String memberId); |
|
41 |
+ |
|
23 | 42 |
} |
+++ src/main/java/kr/co/takensoft/ai/system/auth/service/RefreshService.java
... | ... | @@ -0,0 +1,23 @@ |
1 | +package kr.co.takensoft.ai.system.auth.service; | |
2 | + | |
3 | +import jakarta.servlet.http.HttpServletRequest; | |
4 | +import jakarta.servlet.http.HttpServletResponse; | |
5 | + | |
6 | +/* | |
7 | + * @author : 박민혁 | |
8 | + * @since : 2025.07.09 | |
9 | + * @modification | |
10 | + * since | author | description | |
11 | + * 2025.07.09 | 박민혁 | 최초 등록 | |
12 | + * | |
13 | + * 리프레시 토큰 관련 서비스 | |
14 | + */ | |
15 | +public interface RefreshService { | |
16 | + /** | |
17 | + * @param req, res 클라이언트 요청과 서버 응답 | |
18 | + * @return 액세스 토큰 정보 | |
19 | + * | |
20 | + * 토큰 재발급 | |
21 | + */ | |
22 | + String tokenReissueProc(HttpServletRequest req, HttpServletResponse res) throws Exception; | |
23 | +} |
--- src/main/java/kr/co/takensoft/ai/system/auth/service/impl/AuthServiceImpl.java
+++ src/main/java/kr/co/takensoft/ai/system/auth/service/impl/AuthServiceImpl.java
... | ... | @@ -10,14 +10,22 @@ |
10 | 10 |
* 사용자 정보 관련 서비스 |
11 | 11 |
*/ |
12 | 12 |
import kr.co.takensoft.ai.system.auth.dao.AuthDAO; |
13 |
+import kr.co.takensoft.ai.system.auth.dao.RefreshDAO; |
|
14 |
+import kr.co.takensoft.ai.system.auth.dto.LoginDTO; |
|
15 |
+import kr.co.takensoft.ai.system.auth.dto.RefreshTokenDTO; |
|
16 |
+import kr.co.takensoft.ai.system.auth.dto.TokenDTO; |
|
13 | 17 |
import kr.co.takensoft.ai.system.auth.service.AuthService; |
14 | 18 |
import kr.co.takensoft.ai.system.auth.vo.MemberVO; |
15 | 19 |
import kr.co.takensoft.ai.system.common.idgen.service.IdgenService; |
20 |
+import kr.co.takensoft.ai.system.common.util.JwtUtil; |
|
16 | 21 |
import kr.co.takensoft.ai.system.common.util.Secret; |
17 | 22 |
import lombok.RequiredArgsConstructor; |
18 | 23 |
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; |
19 | 24 |
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
20 | 25 |
import org.springframework.stereotype.Service; |
26 |
+ |
|
27 |
+import java.util.HashMap; |
|
28 |
+import java.util.Map; |
|
21 | 29 |
|
22 | 30 |
@Service |
23 | 31 |
@RequiredArgsConstructor |
... | ... | @@ -26,10 +34,12 @@ |
26 | 34 |
private final AuthDAO authDAO; |
27 | 35 |
private final BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); |
28 | 36 |
private final IdgenService memberIdgn; |
37 |
+ private final JwtUtil jwtUtil; |
|
38 |
+ private final RefreshDAO refreshDAO; |
|
29 | 39 |
|
30 | 40 |
/** |
31 | 41 |
* @param member 사용자 정보 |
32 |
- * @return 등록 성공 여부 |
|
42 |
+ * @return int 등록 성공 여부 |
|
33 | 43 |
* |
34 | 44 |
* 사용자 회원가입 |
35 | 45 |
*/ |
... | ... | @@ -45,6 +55,55 @@ |
45 | 55 |
e.printStackTrace(); |
46 | 56 |
return -1; |
47 | 57 |
} |
48 |
- }; |
|
58 |
+ } |
|
59 |
+ |
|
60 |
+ |
|
61 |
+ /** |
|
62 |
+ * @param LoginDTO 로그인 정보 |
|
63 |
+ * @return Map<String, String> 액세스 토큰과 리프레시 토큰 |
|
64 |
+ * |
|
65 |
+ * 사용자 회원가입 |
|
66 |
+ */ |
|
67 |
+ public Map<String, String> memberLogin(LoginDTO loginDTO) throws Exception{ |
|
68 |
+ MemberVO member = authDAO.findMemberInfo(loginDTO.getLoginId()); |
|
69 |
+ if (member == null) { |
|
70 |
+ throw new Exception("잘못된 아이디입니다"); // 아이디가 없을 경우 |
|
71 |
+ } |
|
72 |
+ if(!bCryptPasswordEncoder.matches(loginDTO.getPassword(), member.getPassword())) { |
|
73 |
+ throw new Exception("잘못된 비밀번호입니다"); // 비밀번호가 틀릴 경우 |
|
74 |
+ } |
|
75 |
+ |
|
76 |
+ TokenDTO tokenDTO = new TokenDTO(member.getLoginId(), member.getMemberId(), member.getMemberName()); // 멤버 정보로 액세스 토큰 DTO 생성 |
|
77 |
+ |
|
78 |
+ String accessToken = jwtUtil.createAccessToken(tokenDTO); // 액세스 토큰 생성 |
|
79 |
+ String refreshToken = jwtUtil.createRefreshToken(member.getMemberId()); // 리프레시 토큰 생성 |
|
80 |
+ |
|
81 |
+ RefreshTokenDTO refreshTokenDTO = new RefreshTokenDTO(member.getMemberId(), refreshToken); // 리프레시 토큰 DTO 생성 |
|
82 |
+ |
|
83 |
+ refreshDAO.saveRefreshToken(refreshTokenDTO); // 리프레시 토큰 저장 |
|
84 |
+ |
|
85 |
+ Map<String, String> tokens = new HashMap<>(); |
|
86 |
+ tokens.put("accessToken", accessToken); |
|
87 |
+ tokens.put("refreshToken", refreshToken); |
|
88 |
+ return tokens; |
|
89 |
+ } |
|
90 |
+ |
|
91 |
+ /** |
|
92 |
+ * @param memberId 사용자 아이디 |
|
93 |
+ * @return MemberVO 사용자 정보 |
|
94 |
+ * |
|
95 |
+ * 사용자 정보 개인 정보 조회 |
|
96 |
+ */ |
|
97 |
+ public MemberVO findMemberInfo(String memberId){ |
|
98 |
+ try { |
|
99 |
+ MemberVO member = authDAO.findMemberInfo(memberId); |
|
100 |
+ member.setEmail(Secret.decrypt(member.getEmail())); // 이메일 복호화 |
|
101 |
+ member.setPhoneNumber(Secret.decrypt(member.getPhoneNumber())); // 전화번호 복호화 |
|
102 |
+ return member; |
|
103 |
+ } catch (Exception e) { |
|
104 |
+ e.printStackTrace(); |
|
105 |
+ return null; |
|
106 |
+ } |
|
107 |
+ } |
|
49 | 108 |
|
50 | 109 |
} |
+++ src/main/java/kr/co/takensoft/ai/system/auth/service/impl/RefreshServiceImpl.java
... | ... | @@ -0,0 +1,87 @@ |
1 | +package kr.co.takensoft.ai.system.auth.service.impl; | |
2 | + | |
3 | +import io.jsonwebtoken.ExpiredJwtException; | |
4 | +import jakarta.servlet.http.HttpServletRequest; | |
5 | +import jakarta.servlet.http.HttpServletResponse; | |
6 | +import kr.co.takensoft.ai.system.auth.dao.AuthDAO; | |
7 | +import kr.co.takensoft.ai.system.auth.dao.RefreshDAO; | |
8 | +import kr.co.takensoft.ai.system.auth.dto.TokenDTO; | |
9 | +import kr.co.takensoft.ai.system.auth.service.RefreshService; | |
10 | +import kr.co.takensoft.ai.system.auth.vo.MemberVO; | |
11 | +import kr.co.takensoft.ai.system.common.util.JwtUtil; | |
12 | +import lombok.RequiredArgsConstructor; | |
13 | +import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; | |
14 | +import org.springframework.stereotype.Service; | |
15 | + | |
16 | +/* | |
17 | + * @author : 박민혁 | |
18 | + * @since : 2025.07.09 | |
19 | + * @modification | |
20 | + * since | author | description | |
21 | + * 2025.07.09 | 박민혁 | 최초 등록 | |
22 | + * | |
23 | + * 리프레시 토큰 관련 서비스 | |
24 | + */ | |
25 | +@Service | |
26 | +@RequiredArgsConstructor | |
27 | +public class RefreshServiceImpl extends EgovAbstractServiceImpl implements RefreshService { | |
28 | + /** | |
29 | + * @param req, res 클라이언트 요청과 서버 응답 | |
30 | + * @return 액세스 토큰 정보 | |
31 | + * | |
32 | + * 토큰 재발급 | |
33 | + */ | |
34 | + private final JwtUtil jwtUtil; | |
35 | + private final AuthDAO authDAO; | |
36 | + private final RefreshDAO refreshDAO; | |
37 | + | |
38 | + public String tokenReissueProc(HttpServletRequest req, HttpServletResponse res) throws Exception { | |
39 | + String refreshToken = req.getHeader("RefreshToken"); | |
40 | + if (refreshToken == null) { | |
41 | + throw new Exception("Refresh token이 전달되지 않았습니다."); | |
42 | + } | |
43 | + String memberId; | |
44 | + try { | |
45 | + // memberId 먼저 추출: 유효기간 만료되어도 대부분 파싱 가능 | |
46 | + memberId = jwtUtil.getUsid(refreshToken); | |
47 | + } catch (Exception e) { | |
48 | + throw new Exception("Refresh token에서 사용자 정보를 파싱할 수 없습니다."); | |
49 | + } | |
50 | + | |
51 | + // 리프레시 토큰 만료 여부 확인 | |
52 | + try { | |
53 | + // 만료 여부 체크 | |
54 | + if (jwtUtil.isExpired(refreshToken)) { | |
55 | + refreshDAO.deleteRefreshToken(memberId); | |
56 | + throw new Exception("Refresh token이 만료되었습니다."); | |
57 | + } | |
58 | + } catch (ExpiredJwtException e) { | |
59 | + // 여기서도 따로 만료된 경우 캐치 | |
60 | + refreshDAO.deleteRefreshToken(memberId); | |
61 | + throw new Exception("Refresh token이 만료되었습니다."); | |
62 | + } | |
63 | + | |
64 | + // 리프레시 토큰이 DB에 존재하는지 확인 | |
65 | + if (refreshDAO.getRefreshTokenByUserId(memberId) == null) { | |
66 | + throw new Exception("리프레시 토큰이 존재하지 않습니다."); | |
67 | + } | |
68 | + | |
69 | + // 사용자 정보 조회 | |
70 | + MemberVO member = authDAO.findMemberInfo(memberId); | |
71 | + if (member == null) { | |
72 | + refreshDAO.deleteRefreshToken(memberId); // 자동 로그아웃 | |
73 | + throw new Exception("유효한 사용자가 아닙니다."); | |
74 | + } | |
75 | + | |
76 | + // 멤버 정보를 가져와 DTO 생성 | |
77 | + TokenDTO tokenDTO = new TokenDTO(member.getLoginId(), member.getMemberId(), member.getMemberName()); | |
78 | + | |
79 | + // 새 액세스 토큰 생성: 이름, 권한 등도 포함하여 재발급 | |
80 | + String newAccessToken = jwtUtil.createAccessToken(tokenDTO); | |
81 | + | |
82 | + // 응답 헤더에 새 액세스 토큰 설정 (Controller에서 이미 설정할 수도 있음) | |
83 | + res.setHeader("Authorization", newAccessToken); | |
84 | + | |
85 | + return newAccessToken; | |
86 | + } | |
87 | +} |
--- src/main/java/kr/co/takensoft/ai/system/auth/web/AuthController.java
+++ src/main/java/kr/co/takensoft/ai/system/auth/web/AuthController.java
... | ... | @@ -1,5 +1,6 @@ |
1 | 1 |
package kr.co.takensoft.ai.system.auth.web; |
2 | 2 |
|
3 |
+import kr.co.takensoft.ai.system.auth.dto.LoginDTO; |
|
3 | 4 |
import kr.co.takensoft.ai.system.auth.service.AuthService; |
4 | 5 |
import kr.co.takensoft.ai.system.auth.vo.MemberVO; |
5 | 6 |
import lombok.RequiredArgsConstructor; |
... | ... | @@ -11,6 +12,7 @@ |
11 | 12 |
import org.springframework.web.bind.annotation.RestController; |
12 | 13 |
|
13 | 14 |
import java.util.HashMap; |
15 |
+import java.util.Map; |
|
14 | 16 |
|
15 | 17 |
/* |
16 | 18 |
* @author : 박민혁 |
... | ... | @@ -41,5 +43,25 @@ |
41 | 43 |
return new ResponseEntity<>(result, HttpStatus.OK); |
42 | 44 |
} |
43 | 45 |
|
46 |
+ /** |
|
47 |
+ * @param loginDTO 로그인 정보 |
|
48 |
+ * @return ResponseEntity 액세스 토큰 / 리프레시 토큰을 포함하는 응답 |
|
49 |
+ * |
|
50 |
+ * 사용자 회원 가입 |
|
51 |
+ */ |
|
52 |
+ @PostMapping("/login.json") |
|
53 |
+ public ResponseEntity<?> login(@RequestBody LoginDTO loginDTO) throws Exception { |
|
54 |
+ HashMap<String, Object> result = new HashMap<>(); |
|
55 |
+ try { |
|
56 |
+ Map<String, String> tokens = authService.memberLogin(loginDTO); |
|
57 |
+ result.put("accessToken", tokens.get("accessToken")); |
|
58 |
+ result.put("refreshToken", tokens.get("refreshToken")); |
|
59 |
+ return new ResponseEntity<>(result, HttpStatus.OK); |
|
60 |
+ } catch (Exception e) { |
|
61 |
+ result.put("message", e.getMessage()); |
|
62 |
+ return new ResponseEntity<>(result, HttpStatus.UNAUTHORIZED); |
|
63 |
+ } |
|
64 |
+ } |
|
65 |
+ |
|
44 | 66 |
|
45 | 67 |
}(No newline at end of file) |
+++ src/main/java/kr/co/takensoft/ai/system/auth/web/RefreshController.java
... | ... | @@ -0,0 +1,51 @@ |
1 | +package kr.co.takensoft.ai.system.auth.web; | |
2 | + | |
3 | +import jakarta.servlet.http.HttpServletRequest; | |
4 | +import jakarta.servlet.http.HttpServletResponse; | |
5 | +import kr.co.takensoft.ai.system.auth.service.RefreshService; | |
6 | +import lombok.RequiredArgsConstructor; | |
7 | +import org.springframework.http.HttpStatus; | |
8 | +import org.springframework.http.ResponseEntity; | |
9 | +import org.springframework.web.bind.annotation.PostMapping; | |
10 | +import org.springframework.web.bind.annotation.RequestMapping; | |
11 | +import org.springframework.web.bind.annotation.RestController; | |
12 | + | |
13 | +import java.util.HashMap; | |
14 | +import java.util.Map; | |
15 | + | |
16 | +/* | |
17 | + * @author : 박민혁 | |
18 | + * @since : 2025.02.06 | |
19 | + * @modification | |
20 | + * since | author | description | |
21 | + * 2025.02.06 | 박민혁 | 최초 등록 | |
22 | + * 2025.03.20 | 박민혁 | 매핑 주소 수정 | |
23 | + * | |
24 | + * 리프레시 토큰 재발급 컨트롤러 | |
25 | + */ | |
26 | +@RestController | |
27 | +@RequiredArgsConstructor | |
28 | +@RequestMapping(value = "/api/refresh") | |
29 | +public class RefreshController { | |
30 | + private final RefreshService refreshService; | |
31 | + | |
32 | + @PostMapping("/tokenReissue.json") | |
33 | + public ResponseEntity<?> tokenReissue(HttpServletRequest req, HttpServletResponse res) { | |
34 | + try { | |
35 | + // 서비스에서 새 액세스 토큰 재발급 | |
36 | + String newAccessToken = refreshService.tokenReissueProc(req, res); | |
37 | + | |
38 | + // JSON 형태로 새 토큰과 관련 정보를 반환 | |
39 | + Map<String, Object> responseData = new HashMap<>(); | |
40 | + responseData.put("accessToken", newAccessToken); | |
41 | + responseData.put("message", "정상적으로 액세스 토큰이 재발급되었습니다."); | |
42 | + | |
43 | + return new ResponseEntity<>(responseData, HttpStatus.OK); | |
44 | + } catch (Exception e) { | |
45 | + Map<String, Object> responseData = new HashMap<>(); | |
46 | + responseData.put("message", "토큰 재발급에 실패하였습니다: " + e.getMessage()); | |
47 | + return new ResponseEntity<>(responseData, HttpStatus.UNAUTHORIZED); | |
48 | + } | |
49 | + } | |
50 | + | |
51 | +} |
--- src/main/java/kr/co/takensoft/ai/system/common/util/JwtUtil.java
+++ src/main/java/kr/co/takensoft/ai/system/common/util/JwtUtil.java
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 |
|
3 | 3 |
import io.jsonwebtoken.ExpiredJwtException; |
4 | 4 |
import io.jsonwebtoken.Jwts; |
5 |
+import kr.co.takensoft.ai.system.auth.dto.TokenDTO; |
|
5 | 6 |
import org.springframework.beans.factory.annotation.Value; |
6 | 7 |
import org.springframework.stereotype.Component; |
7 | 8 |
|
... | ... | @@ -27,11 +28,11 @@ |
27 | 28 |
} |
28 | 29 |
|
29 | 30 |
// 액세스 토큰 생성 |
30 |
- public String createAccessToken(String userId, String userNm, String userAuth) { |
|
31 |
+ public String createAccessToken(TokenDTO token) { |
|
31 | 32 |
return Jwts.builder() |
32 |
- .claim("userId", userId) |
|
33 |
- .claim("userNm", userNm) |
|
34 |
- .claim("userAuth", userAuth) |
|
33 |
+ .claim("loginId", token.getLoginId()) |
|
34 |
+ .claim("memberId", token.getMemberId()) |
|
35 |
+ .claim("memberName", token.getMemberName()) |
|
35 | 36 |
.issuedAt(new Date(System.currentTimeMillis())) |
36 | 37 |
.expiration(new Date(System.currentTimeMillis() + accessTime)) |
37 | 38 |
.signWith(secretKey) |
... | ... | @@ -39,9 +40,9 @@ |
39 | 40 |
} |
40 | 41 |
|
41 | 42 |
// 리프레시 토큰 생성 |
42 |
- public String createRefreshToken(String userId) { |
|
43 |
+ public String createRefreshToken(String memberId) { |
|
43 | 44 |
return Jwts.builder() |
44 |
- .claim("userId", userId) |
|
45 |
+ .claim("memberId", memberId) |
|
45 | 46 |
.claim("tokenType", "refresh") |
46 | 47 |
.issuedAt(new Date(System.currentTimeMillis())) |
47 | 48 |
.expiration(new Date(System.currentTimeMillis() + refreshTime)) |
... | ... | @@ -55,10 +56,10 @@ |
55 | 56 |
return Jwts.parser().verifyWith(secretKey).build() |
56 | 57 |
.parseSignedClaims(token) |
57 | 58 |
.getPayload() |
58 |
- .get("userId", String.class); |
|
59 |
+ .get("memberId", String.class); |
|
59 | 60 |
} catch (ExpiredJwtException e) { |
60 | 61 |
// 만료된 토큰이어도 claims는 존재하므로 꺼낼 수 있음 |
61 |
- return e.getClaims().get("userId", String.class); |
|
62 |
+ return e.getClaims().get("memberId", String.class); |
|
62 | 63 |
} |
63 | 64 |
} |
64 | 65 |
|
... | ... | @@ -68,21 +69,9 @@ |
68 | 69 |
return Jwts.parser().verifyWith(secretKey).build() |
69 | 70 |
.parseSignedClaims(token) |
70 | 71 |
.getPayload() |
71 |
- .get("userNm", String.class); |
|
72 |
+ .get("memberName", String.class); |
|
72 | 73 |
} catch (ExpiredJwtException e) { |
73 |
- return e.getClaims().get("userNm", String.class); |
|
74 |
- } |
|
75 |
- } |
|
76 |
- |
|
77 |
- // 유저 권한 반환 메서드 (필요시) |
|
78 |
- public String getUserAuth(String token) { |
|
79 |
- try { |
|
80 |
- return Jwts.parser().verifyWith(secretKey).build() |
|
81 |
- .parseSignedClaims(token) |
|
82 |
- .getPayload() |
|
83 |
- .get("userAuth", String.class); |
|
84 |
- } catch (ExpiredJwtException e) { |
|
85 |
- return e.getClaims().get("userAuth", String.class); |
|
74 |
+ return e.getClaims().get("memberName", String.class); |
|
86 | 75 |
} |
87 | 76 |
} |
88 | 77 |
|
--- src/main/resources/mybatis/mapper/auth/auth-SQL.xml
+++ src/main/resources/mybatis/mapper/auth/auth-SQL.xml
... | ... | @@ -33,12 +33,13 @@ |
33 | 33 |
<!-- |
34 | 34 |
작 성 자 : 박민혁 |
35 | 35 |
작 성 일 : 2025.07.08 |
36 |
- 내 용 : 사용자 정보 찾기 (테스트용) |
|
36 |
+ 내 용 : 사용자 정보 개인 정보 조회 |
|
37 | 37 |
--> |
38 |
- <select id="findMemberId" > |
|
38 |
+ <select id="findMemberInfo" > |
|
39 | 39 |
select |
40 |
- member_id |
|
40 |
+ * |
|
41 | 41 |
from member |
42 |
+ where member_id = #{memberId} |
|
42 | 43 |
</select> |
43 | 44 |
|
44 | 45 |
</mapper>(No newline at end of file) |
+++ src/main/resources/mybatis/mapper/auth/refresh-SQL.xml
... | ... | @@ -0,0 +1,47 @@ |
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | +<mapper namespace="kr.co.takensoft.ai.system.auth.dao.RefreshDAO"> | |
4 | + <!-- | |
5 | + 작 성 자 : 박민혁 | |
6 | + 작 성 일 : 2025.04.18 | |
7 | + 내 용 : 리프레시 토큰 저장 혹은 갱신 | |
8 | + --> | |
9 | + <insert id="saveRefreshToken"> | |
10 | + INSERT INTO token_info ( | |
11 | + member_id, | |
12 | + refresh_token, | |
13 | + created_at | |
14 | + ) VALUES ( | |
15 | + #{memberId}, | |
16 | + #{refreshToken}, | |
17 | + CURRENT_TIMESTAMP | |
18 | + ) | |
19 | + ON CONFLICT (member_id) | |
20 | + DO UPDATE | |
21 | + SET | |
22 | + refresh_token = EXCLUDED.refresh_token, | |
23 | + created_at = CURRENT_TIMESTAMP | |
24 | + </insert> | |
25 | + | |
26 | + <!-- | |
27 | + 작 성 자 : 박민혁 | |
28 | + 작 성 일 : 2025.04.18 | |
29 | + 내 용 : 유저 아이디로 리프레시 토큰을 받아오기 | |
30 | + --> | |
31 | + <select id="getRefreshTokenByUserId" resultType="String"> | |
32 | + SELECT refresh_token | |
33 | + FROM token_info | |
34 | + WHERE member_id = #{memberId} | |
35 | + </select> | |
36 | + | |
37 | + <!-- | |
38 | + 작 성 자 : 박민혁 | |
39 | + 작 성 일 : 2025.04.18 | |
40 | + 내 용 : 리프레시 토큰 삭제 | |
41 | + --> | |
42 | + <delete id="deleteRefreshToken"> | |
43 | + DELETE FROM token_info | |
44 | + WHERE member_id = #{memberId} | |
45 | + </delete> | |
46 | + | |
47 | +</mapper>(No newline at end of file) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?