Skip to content

Commit

Permalink
Merge pull request #185 from GEON-PPANG/feature/#183
Browse files Browse the repository at this point in the history
[FEAT] 애플 회원가입 추가 & 닉네임 변경 api 추가
  • Loading branch information
seunghaLim authored Sep 3, 2023
2 parents a232329 + 65e8fa2 commit 8d9253a
Show file tree
Hide file tree
Showing 56 changed files with 801 additions and 581 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ log/
### database files ###
/storage/db-core/src/main/resources/init/h2-data.sql
/storage/db-core/src/main/resources/init/h2-schema.sql

### apple private key-file ###
/api/src/main/resources/*.p8
6 changes: 4 additions & 2 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ dependencies {
// 매퍼 의존성 추가
implementation 'org.mapstruct:mapstruct:1.5.3.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
// annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

// annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

// feign
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:3.1.8'

}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.org.gunbbang.common.dto;
package com.org.gunbbang.common.DTO;

import com.org.gunbbang.errorType.ErrorType;
import com.org.gunbbang.errorType.SuccessType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
"/actuator/health")
.permitAll();

// 소셜 로그인 설정
// http.oauth2Login()
// .successHandler(oAuth2LoginSuccessHandler) // 동의하고 계속하기를 눌렀을 때 Handler 설정
// .failureHandler(oAuth2LoginFailureHandler) // 소셜 로그인 실패 시 핸들러 설정
// .userInfoEndpoint().userService(customOAuth2UserService);

// logout 구현
http.logout()
.logoutUrl("/auth/logout") // 로그아웃 URL 설정
Expand Down Expand Up @@ -119,7 +113,7 @@ public PasswordEncoder passwordEncoder() {

@Bean
public LoginSuccessHandler loginSuccessHandler() {
return new LoginSuccessHandler(jwtService, memberRepository);
return new LoginSuccessHandler(jwtService);
}

@Bean
Expand Down
58 changes: 18 additions & 40 deletions api/src/main/java/com/org/gunbbang/controller/AuthController.java
Original file line number Diff line number Diff line change
@@ -1,69 +1,47 @@
package com.org.gunbbang.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.org.gunbbang.AOP.annotation.SignupApiLog;
import com.org.gunbbang.PlatformType;
import com.org.gunbbang.Role;
import com.org.gunbbang.common.AuthType;
import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.request.MemberSignUpRequestDTO;
import com.org.gunbbang.controller.DTO.response.MemberSignUpResponseDTO;
import com.org.gunbbang.controller.DTO.response.MemberWithdrawResponseDTO;
import com.org.gunbbang.entity.Member;
import com.org.gunbbang.errorType.SuccessType;
import com.org.gunbbang.jwt.service.JwtService;
import com.org.gunbbang.login.AuthServiceProvider;
import com.org.gunbbang.service.AuthServiceProvider;
import com.org.gunbbang.service.MemberService;
import com.org.gunbbang.service.VO.SignedUpMemberVO;
import com.org.gunbbang.util.mapper.MemberMapper;
import com.org.gunbbang.util.security.SecurityUtil;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@Slf4j
public class AuthController {
private final MemberService memberService;
private final AuthServiceProvider authServiceProvider;
private final JwtService jwtService;

@PostMapping("/signup")
@SignupApiLog
// public ApiResponse<MemberSignUpResponseDTO> signUp(
public ResponseEntity<MemberSignUpResponseDTO> signUp(
@RequestHeader(value = "Social-Authorization", required = false)
final String authorizationCode,
@RequestBody final MemberSignUpRequestDTO request)
throws JsonProcessingException {
if (request.getPlatformType().equals(PlatformType.NONE)) {
return ResponseEntity.ok().body(memberService.signUp(request));
}
Member customOAuth2User =
public ApiResponse<MemberSignUpResponseDTO> signUp(
@RequestHeader(value = "Platform-token", required = false) final String platformToken,
@RequestBody final MemberSignUpRequestDTO request,
HttpServletResponse response)
throws Exception {

SignedUpMemberVO vo =
authServiceProvider
.getAuthService(request.getPlatformType())
.loadMemberByToken(authorizationCode, request.getPlatformType());
HttpHeaders httpHeaders = new HttpHeaders();
getSocialLoginMemberToken(customOAuth2User, httpHeaders);
return ResponseEntity.ok()
.headers(httpHeaders)
.body(
MemberSignUpResponseDTO.builder()
.memberId(customOAuth2User.getMemberId())
.type(AuthType.LOGIN)
.email(customOAuth2User.getEmail())
.build());
}
.saveMemberOrLogin(platformToken, request);

private void getSocialLoginMemberToken(Member customOAuth2User, HttpHeaders httpHeaders) {
String accessToken =
jwtService.createAccessToken(customOAuth2User.getEmail(), customOAuth2User.getMemberId());
httpHeaders.add("Authorization", accessToken);
if (customOAuth2User.getRole().equals(Role.USER)) {
String refreshToken = jwtService.createRefreshToken();
jwtService.updateRefreshToken(customOAuth2User.getEmail(), refreshToken);
httpHeaders.add("Authorization-refresh", refreshToken);
}
jwtService.setSignedUpMemberToken(vo, response);
return ApiResponse.success(
SuccessType.SIGNUP_SUCCESS, MemberMapper.INSTANCE.toMemberSignUpResponseDTO(vo));
}

@DeleteMapping("/withdraw")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.AOP.annotation.BakeryIdApiLog;
import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.response.BakeryDetailResponseDTO;
import com.org.gunbbang.controller.DTO.response.BakeryListResponseDTO;
import com.org.gunbbang.controller.DTO.response.ReviewListResponseDTO;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.response.BestBakeryListResponseDTO;
import com.org.gunbbang.controller.DTO.response.BestReviewListResponseDTO;
import com.org.gunbbang.errorType.SuccessType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.AOP.annotation.BakeryIdApiLog;
import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.request.BookMarkRequestDTO;
import com.org.gunbbang.controller.DTO.response.BookMarkResponseDTO;
import com.org.gunbbang.errorType.SuccessType;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.org.gunbbang.controller.DTO.request;

import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@Getter
public class NicknameUpdateRequestDTO {
@NotNull private String nickname;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.org.gunbbang.controller.DTO.response;

import com.org.gunbbang.Role;
import com.org.gunbbang.common.AuthType;
import lombok.*;

Expand All @@ -11,4 +12,5 @@ public class MemberSignUpResponseDTO {
private Long memberId;
private AuthType type;
private String email;
private Role role;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.org.gunbbang.controller.DTO.response;

import com.org.gunbbang.Role;
import lombok.*;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor
@Builder
public class NicknameUpdateResponseDTO {
private String nickname;
private Role role;
private Long memberId;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.request.MemberTypesRequestDTO;
import com.org.gunbbang.controller.DTO.request.NicknameUpdateRequestDTO;
import com.org.gunbbang.controller.DTO.response.*;
import com.org.gunbbang.errorType.SuccessType;
import com.org.gunbbang.jwt.service.JwtService;
import com.org.gunbbang.service.BakeryService;
import com.org.gunbbang.service.MemberService;
import com.org.gunbbang.service.ReviewService;
import com.org.gunbbang.util.security.*;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand All @@ -23,6 +26,7 @@ public class MemberController {
private final MemberService memberService;
private final ReviewService reviewService;
private final BakeryService bakeryService;
private final JwtService jwtService;

@GetMapping("")
@ResponseStatus(HttpStatus.OK)
Expand Down Expand Up @@ -71,4 +75,15 @@ public ApiResponse<MemberNicknameResponseDTO> getLoginMemberNickname() {
SuccessType.GET_MEMBER_NICKNAME_SUCCESS,
MemberNicknameResponseDTO.builder().nickname(nickname).build());
}

/** 소셜로그인을 한 회원이 닉네임 설정 뷰에서 이탈하고(GUEST) 추후에 진입했을 때 사용되는 닉네임 변경 api */
@PostMapping("/nickname")
public ApiResponse<NicknameUpdateResponseDTO> updateLoginMemberNickname(
@RequestBody @Valid final NicknameUpdateRequestDTO request, HttpServletResponse response) {
Long memberId = SecurityUtil.getLoginMemberId();
NicknameUpdateResponseDTO responseDTO =
memberService.updateMemberNickname(memberId, request.getNickname());
jwtService.reIssueTokensAndUpdateRefreshToken(response, responseDTO.getMemberId());
return ApiResponse.success(SuccessType.UPDATE_MEMBER_NICKNAME_SUCCESS, responseDTO);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.request.ReviewReportRequestDTO;
import com.org.gunbbang.controller.DTO.response.ReviewReportResponseDTO;
import com.org.gunbbang.errorType.SuccessType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.AOP.annotation.BakeryIdApiLog;
import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.request.ReviewRequestDTO;
import com.org.gunbbang.controller.DTO.response.ReviewCreateResponseDTO;
import com.org.gunbbang.controller.DTO.response.ReviewDetailResponseDTO;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.org.gunbbang.controller;

import com.org.gunbbang.AOP.annotation.SearchApiLog;
import com.org.gunbbang.common.dto.ApiResponse;
import com.org.gunbbang.common.DTO.ApiResponse;
import com.org.gunbbang.controller.DTO.response.BakerySearchResponseDTO;
import com.org.gunbbang.errorType.SuccessType;
import com.org.gunbbang.service.BakeryService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.org.gunbbang.BadRequestException;
import com.org.gunbbang.CustomJwtTokenException;
import com.org.gunbbang.NotFoundException;
import com.org.gunbbang.entity.Member;
import com.org.gunbbang.errorType.ErrorType;
import com.org.gunbbang.jwt.service.JwtService;
Expand Down Expand Up @@ -40,9 +41,7 @@ public class JwtAuthenticationProcessingFilter extends OncePerRequestFilter {
"/validation/nickname",
"/validation/email",
"/actuator/health",
"/favicon.ico",
"/oauth2/authorization/kakao",
"/login/oauth2/code/kakao");
"/favicon.ico");

private final GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

Expand Down Expand Up @@ -103,39 +102,24 @@ private void refreshAccessAndRefreshTokens(
throw new CustomJwtTokenException(ErrorType.ABUSED_REFRESH_TOKEN_EXCEPTION);
}

ReIssueTokensAndUpdateRefreshToken(response, foundMember);
}

private void ReIssueTokensAndUpdateRefreshToken(
HttpServletResponse response, Member foundMember) {
String reIssuedRefreshToken = reIssueAndUpdateRefreshToken(foundMember);
String reIssuedAccessToken =
jwtService.createAccessToken(foundMember.getEmail(), foundMember.getMemberId());
jwtService.sendAccessAndRefreshToken(response, reIssuedAccessToken, reIssuedRefreshToken);
log.info("엑세스 토큰 및 리프레시 토큰 재발급 완료");
}

/** refreshToken 재발급하고 디비에 반영 후 flush */
private String reIssueAndUpdateRefreshToken(Member member) {
String reIssuedRefreshToken = jwtService.createRefreshToken();
member.updateRefreshToken(reIssuedRefreshToken);
memberRepository.saveAndFlush(member);
return reIssuedRefreshToken;
jwtService.reIssueTokensAndUpdateRefreshToken(response, foundMember);
}

/**
* accessToken 유효성 검사 후 해당 토큰에서 추출한 memberId로 회원 객체 조회 성공 시 saveAuthentication() 호출해서
* Authentication 객체 생성 후 SecurityContext에 저장
*/
public void checkAccessTokenAndAuthentication(HttpServletRequest request)
throws ServletException, IOException {
public void checkAccessTokenAndAuthentication(HttpServletRequest request) {
log.info("일반적인 리소스 접근 요청. 엑세스 토큰 유효성 검사 시작");

String accessToken = jwtService.extractAccessTokenAsString(request);
Long memberId = jwtService.extractMemberIdClaim(accessToken);
System.out.println("memberId = " + memberId);

memberRepository.findById(memberId).ifPresent(this::saveAuthentication);
Member foundMember =
memberRepository
.findById(memberId)
.orElseThrow(() -> new NotFoundException(ErrorType.NOT_FOUND_USER_EXCEPTION));
saveAuthentication(foundMember);
}

/** SecurityContext에 Authentication 객체를 저장 */
Expand Down
Loading

0 comments on commit 8d9253a

Please sign in to comment.