Skip to content

Commit

Permalink
Merge pull request #13 from studio-recoding/feat-mypage-api
Browse files Browse the repository at this point in the history
[feat][fix] mypage api 개발 및 구글 로그인 완료
  • Loading branch information
JeonHaeseung authored Mar 13, 2024
2 parents fd86ad3 + bfbe3fe commit 34fdbec
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 18 deletions.
16 changes: 12 additions & 4 deletions src/main/java/Ness/Backend/domain/auth/oAuth/OAuth2Controller.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package Ness.Backend.domain.auth.oAuth;

import Ness.Backend.domain.auth.oAuth.dto.GoogleResourceDto;
import Ness.Backend.domain.member.entity.Member;
import Ness.Backend.global.auth.AuthUser;
import Ness.Backend.global.common.response.CommonResponse;
Expand All @@ -12,27 +13,34 @@
@RequiredArgsConstructor
public class OAuth2Controller {
private final OAuth2Service oAuth2Service;
@GetMapping("/dev/login/oauth/{registration}")
@Operation(summary = "OAuth 로그인 요청", description = "개발 테스트용 API 입니다. 클라이언트에게 공개되지 않습니다.")
public CommonResponse<?> devSocialLogin(@RequestParam String code, @PathVariable String registration) {
GoogleResourceDto googleResourceDto = oAuth2Service.devSocialLogin(code, registration);
return CommonResponse.getResponse(HttpStatus.OK.value(), "로그인 성공", googleResourceDto);
}

@PostMapping("/login/oauth/{registration}")
@Operation(summary = "로그인 API", description = "구글 계정으로 로그인하는 API 입니다.")
@Operation(summary = "OAuth 로그인 요청", description = "구글 계정으로 로그인하는 API 입니다.")
public CommonResponse<?> socialLogin(@RequestParam String code, @PathVariable String registration) {
String loginMessage = oAuth2Service.socialLogin(code, registration);
return CommonResponse.postResponse(HttpStatus.OK.value(), loginMessage);
}

@PostMapping("/logout/oauth/{registration}")
@Operation(summary = "로그아웃 요청", description = "구글 계정 로그아웃 요청 API 입니다.")
@Operation(summary = "OAuth 로그아웃 요청", description = "구글 계정 로그아웃 요청 API 입니다.")
public void logout(@AuthUser Member member) {
oAuth2Service.logout(member);
}

@DeleteMapping("/withdrawal/oauth/{registration}")
@Operation(summary = "회원탈퇴 요청", description = "구글 계정 회원탈퇴 요청 API 입니다.")
@Operation(summary = "OAuth 회원탈퇴 요청", description = "구글 계정 회원탈퇴 요청 API 입니다.")
public void withdrawal(@AuthUser Member member) {
oAuth2Service.withdrawal(member);
}

@PostMapping("/reIssuance")
@Operation(summary = "JWT access 토큰 재발급 요청", description = "JWT access 토큰 재발급 요청 API 입니다.")
@Operation(summary = "OAuth JWT access 토큰 재발급 요청", description = "JWT access 토큰 재발급 요청 API 입니다.")
public void reIssuance(@AuthUser Member member) {
//추후 구현 예정
//return oAuth2Service.reIssuance(member);
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/Ness/Backend/domain/auth/oAuth/OAuth2Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
import Ness.Backend.global.auth.oAuth.dto.GoogleResourceApi;
import Ness.Backend.global.error.ErrorCode;
import Ness.Backend.global.error.exception.UnauthorizedException;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import org.springframework.core.env.Environment;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.util.Pair;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
Expand All @@ -41,6 +45,12 @@ public class OAuth2Service {
private final GoogleOAuthApi googleOAuthApi;
private final GoogleResourceApi googleResourceApi;

public GoogleResourceDto devSocialLogin(String code, String registration) {
String accessToken = getAccessToken(code, registration);
GoogleResourceDto googleResourceDto = getUserResource(accessToken, registration);
return googleResourceDto;
}

public String socialLogin(String code, String registration) {
/*
* 로직:
Expand All @@ -55,22 +65,23 @@ public String socialLogin(String code, String registration) {
String id = googleResourceDto.getId();
String email = googleResourceDto.getEmail();
String picture = googleResourceDto.getPicture();
String nickname = googleResourceDto.getNickname();

if (checkSignUp(email)){
/* 여기서 response 이루어짐 */
jwtTokenProvider.generateJwtToken(email);
return "로그인에 성공했습니다.";
} else {
socialSignUp(email, id, picture);
socialSignUp(email, id, picture, nickname);
jwtTokenProvider.generateJwtToken(email);
return "회원가입 및 로그인에 성공했습니다.";
}
}

public String socialSignUp(String email, String password, String picture) {
public String socialSignUp(String email, String password, String picture, String nickname) {
/* 프로필 및 맴버 저장 */
try {
memberService.createMember(email, password, picture);
memberService.createMember(email, password, picture, nickname);
return "회원가입이 완료되었습니다.";

} catch (DataIntegrityViolationException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

@Getter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class GoogleResourceDto {
@JsonProperty("id")
private String id;
Expand All @@ -20,4 +16,15 @@ public class GoogleResourceDto {

@JsonProperty("picture")
private String picture;

@JsonProperty("name")
private String nickname;

@Builder
public GoogleResourceDto(String id, String email, String picture, String nickname){
this.id = id;
this.email = email;
this.picture = picture;
this.nickname = nickname;
}
}
3 changes: 2 additions & 1 deletion src/main/java/Ness/Backend/domain/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ public void deleteMember(Member member) {
memberRepository.save(member);
}

public Member createMember(String email, String password, String picture) {
public Member createMember(String email, String password, String picture, String nickname) {
Member member = Member.builder()
.email(email)
.password(bCryptPasswordEncoder.encode(password)) //비밀번호는 해싱해서 DB에 저장
.build();

Profile profile = Profile.builder()
.pictureUrl(picture)
.nickname(nickname)
.member(member)
.build();

Expand Down
33 changes: 33 additions & 0 deletions src/main/java/Ness/Backend/domain/profile/ProfileController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package Ness.Backend.domain.profile;


import Ness.Backend.domain.auth.dto.LoginRequestDto;
import Ness.Backend.domain.member.entity.Member;
import Ness.Backend.domain.profile.dto.PatchNicknameRequestDto;
import Ness.Backend.domain.profile.dto.ProfileResponseDto;
import Ness.Backend.global.auth.AuthUser;
import Ness.Backend.global.common.response.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class ProfileController {
private final ProfileService profileService;

@GetMapping("/profile")
@Operation(summary = "프로필 조회 API", description = "사용자의 ID로 프로필을 조회하는 API 입니다.")
public ProfileResponseDto userLogin(@AuthUser Member member) {
return profileService.getProfile(member.getId());
}

@PatchMapping("/profile")
@Operation(summary = "프로필 닉네임 변경 API", description = "사용자의 ID로 프로필 닉네임을 변경하는 API 입니다.")
public ResponseEntity<Long> userLogin(@AuthUser Member member, PatchNicknameRequestDto patchNicknameRequestDto) {
Long profileId = profileService.updateNickname(member.getId(), patchNicknameRequestDto.getNickname());
return new ResponseEntity<>(profileId, HttpStatusCode.valueOf(200));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package Ness.Backend.domain.profile;

import Ness.Backend.domain.member.entity.Member;
import Ness.Backend.domain.profile.entity.Profile;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProfileRepository extends JpaRepository<Profile, Long> {

// 특정 맴버 ID로 프로필 반환
Profile findProfileByMember_Id(Long memberId);
}
35 changes: 35 additions & 0 deletions src/main/java/Ness/Backend/domain/profile/ProfileService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package Ness.Backend.domain.profile;

import Ness.Backend.domain.member.entity.Member;
import Ness.Backend.domain.profile.dto.ProfileResponseDto;
import Ness.Backend.domain.profile.entity.Profile;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class ProfileService {
private final ProfileRepository profileRepository;
public Long updateNickname(Long id, String nickname) {
//JPA 변경 감지 사용
Profile profile = profileRepository.findProfileByMember_Id(id);
profile.updateNickname(nickname);

//결과로 profile의 ID 반환
return profile.getId();
}

@Transactional(readOnly = true)
public ProfileResponseDto getProfile(Long id) {
Profile profile = profileRepository.findProfileByMember_Id(id);
ProfileResponseDto profileResponseDto = ProfileResponseDto.builder()
.id(profile.getId())
.pictureUrl(profile.getPictureUrl())
.nickname(profile.getNickname())
.build();

return profileResponseDto;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package Ness.Backend.domain.profile.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class PatchNicknameRequestDto {
@Schema(description = "업데이트할 사용자 닉네임", example = "홍길동")
private String nickname;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package Ness.Backend.domain.profile.dto;


import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class ProfileResponseDto {

@Schema(description = "프로필 고유 아이디", example = "0")
private Long id;

@Schema(description = "사용자의 공유 프로필 URL", example = "https://lh3.googleusercontent.com/...")
private String pictureUrl;

@Schema(description = "사용자의 닉네임", example = "홍길동")
private String nickname;

@Builder
public ProfileResponseDto(Long id, String pictureUrl, String nickname){
this.id = id;
this.pictureUrl = pictureUrl;
this.nickname = nickname;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ public class Profile {

private String pictureUrl;

private String nickname;

@OneToOne
@JoinColumn(name = "member_id")
private Member member;

public void updateNickname(String nickname){
this.nickname = nickname;
}

@Builder
public Profile(String pictureUrl, Member member){
public Profile(String pictureUrl, String nickname, Member member){
this.pictureUrl = pictureUrl;
this.nickname = nickname;
this.member = member;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
import feign.Param;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;

@FeignClient(
name = "GoogleResource",
url = "https://www.googleapis.com")
public interface GoogleResourceApi {
@PostMapping(
@GetMapping(
value = "/oauth2/v2/userinfo",
produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@Headers("Authorization: {authorization}")
GoogleResourceDto googleGetResource(@Param("authorization") String accessToken);
GoogleResourceDto googleGetResource(@RequestHeader("Authorization") String accessToken);
}

0 comments on commit 34fdbec

Please sign in to comment.