첫번째 프로젝트에 이어서 두번째 프로젝트에 대한 포스팅입니다.
프로젝트가 끝나고 시간이 지나서 포스팅이 엉성할 수 있습니다.
제가 맡은 부분에 대해서 기술합니다.
서비스 흐름을 우리가 직접 구성할 수 있고, 배운 내용을 토대로 기능 확장이 가능할 거라 생각했기 때문에 해당 프로젝트를 선정하였다. 학원에서 배운 내용은 일반적인 쇼핑몰을 토대로 CRUD가 다수였다. 하지만 비대면 세탁서비스는 사용자
/관리자
총 2파트로 나눠 흐름을 구성하고, 세부기능을 다양하게 확장할 수 있을 거 같았다.
https://github.com/DDRRDDDD/laundry_garden/tree/main
@PostMapping("/loginPro")
@ResponseBody
public boolean loginPro(@Validated(LoginValidGroup.class)
@RequestBody LoginFormRequest loginForm){
Client client = this.generalLoginService.login(loginForm).getClient();
this.session.setAttribute("loginClient", client);
return true;
}
public @Valid LoginClientCommand login(LoginFormRequest loginForm){
Client client = getClientByLoginForm(loginForm);
return new LoginClientCommand(client);
}
private Client getClientByLoginForm(LoginFormRequest loginForm){
return this.clientRepository.findAll().stream()
.filter(e -> e.equalsForLoginForm(loginForm))
.findFirst()
.orElse(null);
}
3. 설명
로그인 요청을 받아 DB서버로 부터 받은 사용자 정보를 HttpSession에 올린다. Spring validation
으로 로그인 과정 중 ID
,Password
유효성 검사 및 loginClientCommand
DTO 객체로 반환할 때 다시 한번 사용자 정보
가 유효한지 검사한 후 반환한다.
1. 시퀀스 다이어그램
2. 코드
@GetMapping("/{socialSignType}")
public String socialLogin(@RequestParam String code, @PathVariable SocialSignType socialSignType){
SocialLoginInfoDTO loginInfo = socialSignType.getSocialService().getSocialLoginKey(code);
Client client = this.generalLoginService.login(loginInfo).getClient();
this.session.setAttribute("loginClient", client);
return "redirect:/";
}
@Override
public SocialLoginInfoDTO getSocialLoginKey(String authorizationCode){
return SocialLoginInfoDTO.builder()
.socialLoginHost(SocialSignType.KAKAO)
.socialLoginKey(getKakaoKey(accessTokenRequest(authorizationCode)))
.build();
}
private String accessTokenRequest(String code) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> bodys = new LinkedMultiValueMap<>();
bodys.add("grant_type", grantType);
bodys.add("client_id", clientId);
bodys.add("redirect_uri", redirectUri);
bodys.add("code", code);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(bodys, headers);
System.out.println("tokenUrl = " + this.tokenUrl);
ResponseEntity<String> response = restTemplate.postForEntity(tokenUrl, request, String.class);
KaKaoAuthToken accessToken = gson.fromJson(response.getBody(), KaKaoAuthToken.class);
return accessToken.getAccessToken();
}
public String getKakaoKey(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_FORM_URLENCODED);
headers.add("Authorization", "Bearer " + accessToken);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.postForEntity(userInfoUrl, request, String.class);
KakaoProfile kakaoProfile = gson.fromJson(response.getBody(), KakaoProfile.class);
return String.valueOf(kakaoProfile.getId());
}
3. 설명
PathValue
로 받은 해당 소셜 로그인 방법을 받아 회원 정보를 로그인 구현
에서 동일한 방법으로 사용자 정보를 세션에 저장하여 반환합니다
1. 시퀀스 다이어그램
2. 코드
@PostMapping("/registPro")
@ResponseBody
public boolean registPro(@Validated(RegistrationGroup.class)
@RequestBody RegistCommand registCommand){
registCommand = this.registService.clientVerification(registCommand);
this.registService.saveClient(registCommand);
return true;
}
-RegistService
@Transactional
public void saveClient(RegistCommand registCommand) {
if(registCommand.isDuplication())
this.clientRepository.saveAndFlush(createClient(registCommand));
}
public @Valid RegistCommand clientVerification(RegistCommand registCommand) {
this.clientRepository.findAll().stream().anyMatch(registCommand::isSameAs);
return registCommand;
}
private Client createClient(RegistCommand registCommand) {
return Client.builder()
.of(registCommand)
.clientRegDate(DateStamp.getCurrentDate())
.build();
}
3. 설명
회원가입 요청을 받아 DB서버에 사용자 정보를 저장을 한다. 로그인과 마찬가지로 Spring validation
으로 회원가입 과정에서 사용자 정보
의 유효성을 검사한다.
두 번째 프로젝트이지만 또 첫 Spring boot 프로젝트이다. 학원 커리큘럼 상 스프링부트에 대해서 3일 교육을 받고 바로 실전에 투입된 경우이다. 지금 와서 코드를 보면 미숙한 점이 많이 보인다. 이 부분에 대해서는 추후 첫 번째 프로젝트와 더불어 리팩토링 과정을 거칠 예정이다.
이번 프로젝트는 첫 번째 프로젝트랑 다르게 다른 팀원들과 진행하게 되었는데 팀원들과 분위기는 매우 좋게 시작하여 좋게 끝났다. Spring 프로젝트에 대해 기대가 높았던 나에게 해보고 싶은 기술을 도입해보는 것을 적극 추천하였다. 'Spring을 사용하면 제대로 된 웹사이트를 만들 수 있겠지?'
라는 생각을 짓밟듯이 내가 맡은 로그인
/회원가입
에 구현을 완벽히 하지 못하고 끝냈다. 개발 속도이며, Spring을 사용하면 다 될 줄 알았던 오만함이 너무 컸다. 내 개발실력에 더불어 무턱대고 Spring validation
에 대해서 적용과 무리하게 소셜 로그인을 적용하였던 게 화근이었다. 그 과정에서 배운 점도 물론 있지만 팀 프로젝트는 자아실현의 공간이 아닐뿐더러 충분한 계획 즉, 준비가 되어있어야 한다 생각했다.
첫 번째 프로젝트의 회고를 작성하고 이번 회고를 작성하는데 나에 대한 단점에 대해서 명확해지는 거 같고 공통된 문제점에 대해서도 보인다. 아이디어를 개진하는 것은 분명 좋은 일인 거 같다 하지만 나는 그 준비가 되지 않았다
아직은 나를 개발자
라 불리기엔 무리가 있고 이번 프로젝트와 다르게 혼자 골똘히 생각해보아도 아직 부족한 점이 많은 거 같다. 이번 프로젝트를 끝으로 수료까지 마쳤고,
취업을 미루고 다시 한번 공부에 임하기로 하였다.