์ด์ ๊ฒ์๋ฌผ์์ ์นด์นด์ค ์๋ฒ๋ก๋ถํฐ ์ก์ธ์ค ํ ํฐ์ ๋ฐ์๋ค. ์ฆ, ์์์๋ฒ์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ์ป์ ๊ฒ์ด๋ค.
์ก์ธ์ค ํ ํฐ์ด ์์ฒ๋ผ ์๋ต๋์๋๋ฐ, ์ด๋ ๊ฒ ๋ธ๋ผ์ฐ์ ์ ๋ฟ๋ ค์ ธ ์๋ json ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ํ๋ค๊ธฐ ๋๋ฌธ์ model์ ํ๋ ๋ง๋ค์๋ค.
< OAuthToken >
import lombok.Data;
@Data
public class OAuthToken {
private String access_token;
private String token_type;
private String refresh_token;
private int expires_in;
private String scope;
private int refresh_token_expires_in;
}
์ก์ธ์ค ํ ํฐ์ผ๋ก ์นด์นด์ค ์์ ์๋ฒ์ ์์ฒญํ๊ธฐ!
< UserController >
.
.
.
RestTemplate rt2 = new RestTemplate();
// HttpHeader ๊ฐ์ฒด ์์ฑ
HttpHeaders headers2 = new HttpHeaders();
headers2.add("Authorization", "Bearer " + oauthToken.getAccess_token());
headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // key=value ํํ์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๋ ๋ถ๋ถ
// HttpHeader๋ฅผ ๊ฐ์ฒด์ ๋ด๊ธฐ -> ๋ง๋ ์ด์ : ์๋์ exchange ํจ์์ HttpEntity๋ฅผ ๋ฃ์ด์ผ ํด์..
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest2 =
new HttpEntity<>(headers2); // headers ๊ฐ์ ๊ฐ์ง๊ณ ์๋ Entity
// ์นด์นด์ค์๊ฒ Http ์์ฒญํ๊ธฐ (POST ๋ฐฉ์) -> response2๋ผ๋ ๋ณ์์ ์๋ต์ ๋ฐ์
ResponseEntity<String> response2 = rt2.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoProfileRequest2,
String.class
);
.
.
.
return "์ก์ธ์ค ํ ํฐ์ผ๋ก ํ์์ ๋ณด ์์ฒญ : ํ์์ ๋ณด ์์ฒญ์ ๋ํ ์๋ต : " + response2.getBody();
jsonschema2pojo์์ ์์ json ๋ฐ์ดํฐ๋ฅผ ์๋ฐ ๊ฐ์ฒด๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์๋ต ๋ฐ๊ธฐ!
.
.
.
// kakaoProfile์ ์๋ต ๋ฐ์ดํฐ ๋ด๊ธฐ
// json ๋ฐ์ดํฐ๋ฅผ ์๋ฐ์์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋ฐ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
// ๊ฐ์ฒด(ํ์ฌ๋ OAuthToken)์ ๋ด์ ๋ ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ : Gson, Json Simple, ObjectMapper
ObjectMapper objectMapper2 = new ObjectMapper();
KakaoProfile kakaoProfile = null;
try {
kakaoProfile = objectMapper2.readValue(response2.getBody(), KakaoProfile.class);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// User ์ค๋ธ์ ํธ : id, username, password, email, role, createDate
System.out.println("์นด์นด์ค ์์ด๋(๋ฒํธ) : " + kakaoProfile.getId());
System.out.println("์นด์นด์ค ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
// return "์นด์นด์ค ์ธ์ฆ ์๋ฃ : ์ฝ๋๊ฐ : " + code;
// return "์นด์นด์ค ํ ํฐ ์์ฒญ ์๋ฃ : ํ ํฐ์์ฒญ์ ๋ํ ์๋ต : " + response.getBody();
return "์ก์ธ์ค ํ ํฐ์ผ๋ก ํ์์ ๋ณด ์์ฒญ : ํ์์ ๋ณด ์์ฒญ์ ๋ํ ์๋ต : " + response2.getBody();
์ฑ๊ณต !!
์ด์ ์นด์นด์ค๋ก ๋ก๊ทธ์ธ ํ ์ ์ ์ ๋ณด๋ฅผ ๋์ ํ๋ก์ ํธ User ๊ฐ์ฒด๋ก ์ ๋ณด๋ฅผ ๊ตฌ์ฑํด์ผ ํ๋ค. (ํตํฉ)
.
.
.
// User ์ค๋ธ์ ํธ : (id), username, password, email, (role), (createDate)
System.out.println("์นด์นด์ค ์์ด๋(๋ฒํธ) : " + kakaoProfile.getId());
System.out.println("์นด์นด์ค ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ ์ ๋ค์ : " + kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
UUID garbagePassword = UUID.randomUUID();
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ํจ์ค์๋ : " + garbagePassword);
.
.
.
.
.
.
// User ์ค๋ธ์ ํธ : (id), username, password, email, (role), (createDate)
System.out.println("์นด์นด์ค ์์ด๋(๋ฒํธ) : " + kakaoProfile.getId());
System.out.println("์นด์นด์ค ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ ์ ๋ค์ : " + kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
UUID garbagePassword = UUID.randomUUID();
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ํจ์ค์๋ : " + garbagePassword);
User user = User.builder()
.username(kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId())
.password(garbagePassword.toString())
.email(kakaoProfile.getKakao_account().getEmail())
.build();
userService.ํ์๊ฐ์
(user);
return "ํ์๊ฐ์
์๋ฃ";
.
.
.
์ฌ๊ธฐ์ ์ถ๊ฐ๋ก,
userService.ํ์๊ฐ์
(user)
์ ์ ์ด๋ฏธ ๊ฐ์
์ด ๋์๋์ง ์๋์ง ์ฒดํฌ ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๊ฒ์ด๋ค.
.
.
.
// User ์ค๋ธ์ ํธ : (id), username, password, email, (role), (createDate)
System.out.println("์นด์นด์ค ์์ด๋(๋ฒํธ) : " + kakaoProfile.getId());
System.out.println("์นด์นด์ค ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ ์ ๋ค์ : " + kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
UUID garbagePassword = UUID.randomUUID();
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ํจ์ค์๋ : " + garbagePassword);
User user = User.builder()
.username(kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId())
.password(garbagePassword.toString())
.email(kakaoProfile.getKakao_account().getEmail())
.build();
.
.
.
// ๊ฐ์
์ ํน์ ๋น๊ฐ์
์ ๋ถ๊ธฐ (์ด๋ฏธ ํ์์ธ์ง ์๋์ง ์ฒดํฌ)
User originUser = userService.ํ์์ฐพ๊ธฐ(kakaoUser.getUsername());
// ๋น๊ฐ์
์(null)์ด๋ฉด, ํ์๊ฐ์
ํ ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
if (originUser.getUsername() == null) {
System.out.println("๊ธฐ์กด ํ์์ด ์๋๋๋ค.");
userService.ํ์๊ฐ์
(kakaoUser);
// ๊ฐ์
์์ด๋ฉด ํ์๊ฐ์
์์ด ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(kakaoUser.getUsername(), kakaoUser.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/";
์์ฒ๋ผ ์ฝ๋๋ฅผ ๊ตฌํํ์๋๋ฐ.. ๊ณ์ํด์ ์ค๋ฅ๊ฐ ๋ฌ๋ค.
๊ทธ ์ด์ ๋,
๋ธ๋ก๊ทธ์๋ฒ ํจ์ค์๋๋ฅผ UUID๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ธฐ์กด ํ์์ด ์๋๋ผ๋ฉด ์๊ด์ด ์๊ฒ ์ง๋ง ๊ธฐ์กด ํ์์ด๋ผ๋ฉด.. UUID๋ก ๋ง๋ค๋ฉด ์ค๋ณต๋์ง ์๋ ์ด๋ค ํน์ ๊ฐ์ ๋ง๋ค์ด๋ด๊ฒ ๋๋๋ฐ ์ด๊ฒ ๋งค๋ฒ ๋ก๊ทธ์ธ ๋ง๋ค ๋ฐ๋์ด ๋ก๊ทธ์ธ ์ฒ๋ฆฌ๊ฐ ๋์ง ์๋ ๊ฒ์ด์๋ค.
๊ฐ์ด ๋งค๋ฒ ๋ฌ๋ผ์ง๋๊น ๋น์ฐํ ๋ก๊ทธ์ธ์ด ์๋๋ค!!
๋ฐ๋ผ์ ์นด์นด์ค๋ก ๋ก๊ทธ์ธํ๋ ๋ชจ๋ ๋ธ๋ก๊ทธ ์๋ฒ ํจ์ค์๋๋ฅผ ํต์ผํ๊ธฐ๋ก ํ๋ค.
< application.yml >
yj:
key: yj0118
key ์์ ์คํ์ด์ค ๋ ์นธ! key:
์ yj0118
์์ ์คํ์ด์ค ํ ์นธ!!
โญ(์ค์ ํ๋ก์ ํธ์๋ค๋ฉด ์ด ๊ฐ์ ์ ๋ง ์ค์ํ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๋ ธ์ถ๋๋ฉด ์๋๋ค. ์ด key๊ฐ ๋ ธ์ถ๋๋ฉด ๋ชจ๋ OAuth ๋ก๊ทธ์ธ์ด ๋ ธ์ถ๋๊ฒ ๋๋ค.)
์ด์ , ์ด key๋ฅผ UserController์๋ค๊ฐ ์ฃผ์ ํ๋ค.
< UserController >์ ์ฃผ์
@Value("${yj.key}")
private String yjKey;
< UserService >
@Transactional(readOnly = true) // select๋ง ํ๊ธฐ ๋๋ฌธ์ readonly
public User ํ์์ฐพ๊ธฐ(String username) {
User user = userRepository.findByUsername(username).orElseGet(()->{ // .orElseGet : ํ์์ ์ฐพ์๋๋ฐ ์์ผ๋ฉด, ๋น ๊ฐ์ฒด ๋ฆฌํด
return new User();
});
return user;
}
< UserController > ์ต์ข
.
.
.
@GetMapping("/auth/kakao/callback")
public String kakaoCallback(String code) { // @ResponseBody : Data๋ฅผ ๋ฆฌํดํด์ฃผ๋ ์ปจํธ๋กค๋ฌ ํจ์
// ์นด์นด์ค API ์๋ฒ์๊ฒ POST ๋ฐฉ์์ผ๋ก key=value ๋ฐ์ดํฐ๋ฅผ ์์ฒญ
// ์์ฒญ ๋ฐฉ๋ฒ -> ์ฌ๋ฌ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ : HttpsURLConnection, Retrofit2(์ฃผ๋ก ์๋๋ก์ด๋), OkHttp, RestTemplate
RestTemplate rt = new RestTemplate();
// HttpHeader ๊ฐ์ฒด ์์ฑ
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // key=value ํํ์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๋ ๋ถ๋ถ
// HttpBody ๊ฐ์ฒด ์์ฑ
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "d5526e3b2a4169a3d9f2b7a6f9a12cdf");
params.add("redirect_uri", "http://localhost:8000/auth/kakao/callback");
params.add("code", code);
// HttpHeader์ HttpBody๋ฅผ ํ๋์ ๊ฐ์ฒด์ ๋ด๊ธฐ -> ๋ง๋ ์ด์ : ์๋์ exchange ํจ์์ HttpEntity๋ฅผ ๋ฃ์ด์ผ ํด์..
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(params, headers); // body ๋ฐ์ดํฐ์ headers ๊ฐ์ ๊ฐ์ง๊ณ ์๋ Entity
// ์นด์นด์ค์๊ฒ Http ์์ฒญํ๊ธฐ (POST ๋ฐฉ์) -> response๋ผ๋ ๋ณ์์ ์๋ต์ ๋ฐ์
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
// oauthToken์ ์๋ต ๋ฐ์ดํฐ ๋ด๊ธฐ
// json ๋ฐ์ดํฐ๋ฅผ ์๋ฐ์์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋ฐ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
// ๊ฐ์ฒด(ํ์ฌ๋ OAuthToken)์ ๋ด์ ๋ ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ : Gson, Json Simple, ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
OAuthToken oauthToken = null;
try {
oauthToken = objectMapper.readValue(response.getBody(), OAuthToken.class);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println("์นด์นด์ค ์์ธ์ค ํ ํฐ : " + oauthToken.getAccess_token());
// ------------------------------------------------------------------------------------
RestTemplate rt2 = new RestTemplate();
// HttpHeader ๊ฐ์ฒด ์์ฑ
HttpHeaders headers2 = new HttpHeaders();
headers2.add("Authorization", "Bearer " + oauthToken.getAccess_token());
headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // key=value ํํ์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๋ ๋ถ๋ถ
// HttpHeader๋ฅผ ๊ฐ์ฒด์ ๋ด๊ธฐ -> ๋ง๋ ์ด์ : ์๋์ exchange ํจ์์ HttpEntity๋ฅผ ๋ฃ์ด์ผ ํด์..
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest2 =
new HttpEntity<>(headers2); // headers ๊ฐ์ ๊ฐ์ง๊ณ ์๋ Entity
// ์นด์นด์ค์๊ฒ Http ์์ฒญํ๊ธฐ (POST ๋ฐฉ์) -> response2๋ผ๋ ๋ณ์์ ์๋ต์ ๋ฐ์
ResponseEntity<String> response2 = rt2.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoProfileRequest2,
String.class
);
// kakaoProfile์ ์๋ต ๋ฐ์ดํฐ ๋ด๊ธฐ
// json ๋ฐ์ดํฐ๋ฅผ ์๋ฐ์์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋ฐ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
// ๊ฐ์ฒด(ํ์ฌ๋ OAuthToken)์ ๋ด์ ๋ ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ : Gson, Json Simple, ObjectMapper
ObjectMapper objectMapper2 = new ObjectMapper();
KakaoProfile kakaoProfile = null;
try {
kakaoProfile = objectMapper2.readValue(response2.getBody(), KakaoProfile.class);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// User ์ค๋ธ์ ํธ : (id), username, password, email, (role), (createDate)
System.out.println("์นด์นด์ค ์์ด๋(๋ฒํธ) : " + kakaoProfile.getId());
System.out.println("์นด์นด์ค ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ ์ ๋ค์ : " + kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId());
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ์ด๋ฉ์ผ : " + kakaoProfile.getKakao_account().getEmail());
UUID garbagePassword = UUID.randomUUID();
// UUID๋ ์ค๋ณต๋์ง ์๋ ์ด๋ค ํน์ ๊ฐ์ ๋ง๋ค์ด๋ด๋ ์๊ณ ๋ฆฌ์ฆ
System.out.println("๋ธ๋ก๊ทธ์๋ฒ ํจ์ค์๋ : " + yjKey);
User kakaoUser = User.builder()
.username(kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId())
.password(yjKey)
.email(kakaoProfile.getKakao_account().getEmail())
.build();
// ๊ฐ์
์ ํน์ ๋น๊ฐ์
์ ๋ถ๊ธฐ (์ด๋ฏธ ํ์์ธ์ง ์๋์ง ์ฒดํฌ)
User originUser = userService.ํ์์ฐพ๊ธฐ(kakaoUser.getUsername());
// ๋น๊ฐ์
์(null)์ด๋ฉด, ํ์๊ฐ์
ํ ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
if (originUser.getUsername() == null) {
System.out.println("๊ธฐ์กด ํ์์ด ์๋๊ธฐ์ ์๋์ผ๋ก ํ์๊ฐ์
์ ์งํํฉ๋๋ค.");
userService.ํ์๊ฐ์
(kakaoUser);
}
System.out.println("์๋ ๋ก๊ทธ์ธ์ ์งํํฉ๋๋ค.");
// ๊ฐ์
์์ด๋ฉด ํ์๊ฐ์
์์ด ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(kakaoUser.getUsername(), yjKey));
SecurityContextHolder.getContext().setAuthentication(authentication);
// return "์นด์นด์ค ์ธ์ฆ ์๋ฃ : ์ฝ๋๊ฐ : " + code;
// return "์นด์นด์ค ํ ํฐ ์์ฒญ ์๋ฃ : ํ ํฐ์์ฒญ์ ๋ํ ์๋ต : " + response.getBody();
// return "์ก์ธ์ค ํ ํฐ์ผ๋ก ํ์์ ๋ณด ์์ฒญ : ํ์์ ๋ณด ์์ฒญ์ ๋ํ ์๋ต : " + response2.getBody();
// return "ํ์๊ฐ์
์๋ฃ";
return "redirect:/";
}
์ฒซ ์นด์นด์ค ๋ก๊ทธ์ธ์์๋ ํ์๊ฐ์
๊น์ง ์ด๋ฃจ์ด์ ธ DB์ ์ ๋ค์ด๊ฐ์ง๊ณ ,
๊ทธ ์ดํ์๋ ์๋์ผ๋ก ๋ก๊ทธ์ธ์ด ๋๋ค!
์ฌ๊ธฐ์ password๋ yjkey๊ฐ ์ํธํ ๋์ด ๋ค์ด๊ฐ ์๋ ๊ฒ์ด๋ค.
OAuth ๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ํ์์ ๋ณด ์์ ์ ํ๊ฒ ๋๋ค๋ฉด,
์ฆ ๋น๋ฐ๋ฒํธ ์์ ์ ํ๊ฒ ๋๋ค๋ฉด
๊ธฐ์กด์ yjkey(yj0118)๋ก ๋ฃ์ด๋จ๋ ๋น๋ฐ๋ฒํธ๊ฐ ๋ฐ๋๊ฒ ๋์ด ๋ค์ OAuth ๋ก๊ทธ์ธ์ด ๋ถ๊ฐ๋ฅํด์ง ๊ฒ์ด๋ค.
-> User ๊ฐ์ฒด์ oauth ํ๋๋ฅผ ์ถ๊ฐํ์ฌ, ์ด ํ์์ด ์นด์นด์ค๋ก ๋ก๊ทธ์ธํ ํ์์ธ์ง ์ผ๋ฐ ๋ก๊ทธ์ธ์ผ๋ก ๋ก๊ทธ์ธ์ ํ ํ์์ธ์ง ๊ตฌ๋ถํด์ผ ํ๋ค.
์ด๋ ๊ฒ ์นด์นด์ค๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์์๊ฒ๋ oauth ๋ณ์์ "kakao" ๋ผ๋ ๊ฐ์ ์ค๋ค.
๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ๊ตฌ๋ถ์ ํ ์ ์๊ฒ ๋๋ค!
ํ์์์ ํผ์์, oauth ๊ฐ์ด ๋น์ด์์ ๋๋ง ๋น๋ฐ๋ฒํธ๋ฅผ ์์ ํ ์ ์๊ฒ ํ๋ค.
์ฆ, oauth ๊ฐ์ด ๋น์ด์๋ค๋๊ฑด ์นด์นด์ค ๋ก๊ทธ์ธ์ด ์๋ ์ผ๋ฐ ์ฌ์ฉ์๋ผ๋ ๊ฒ!!
< UserService >
UserService์์๋ url ๋ก ๊ณต๊ฒฉ ๋นํ ๊ฒ์ ๋๋นํด ๋ง์์ฃผ๋ ์ฝ๋๋ฅผ ๊ตฌํํ๋ค!!
์ด๋ค ์ ๋ณด๋ ๋ณ๊ฒฝํ ์ ์๋ค.
password์ email ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค!