Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 사용자 중복 여부 확인 API #33

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
145 changes: 78 additions & 67 deletions src/main/java/com/petqa/api/AuthAPIController.java
Original file line number Diff line number Diff line change
@@ -1,111 +1,122 @@
package com.petqa.api;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.petqa.apiPayload.apiPayload.ApiResponse;
import com.petqa.base.Util;
import com.petqa.dto.auth.AuthRequestDTO;
import com.petqa.dto.auth.AuthResponseDTO;
import com.petqa.dto.user.UserRequestDTO;
import com.petqa.service.user.UserCommandService;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthAPIController {

private final UserCommandService userCommandService;

@PostMapping("/login")
public ResponseEntity<ApiResponse<AuthResponseDTO.UserInfoDTO>> login(@RequestBody AuthRequestDTO.SocialLoginDTO loginRequest, HttpServletResponse response) {
AuthResponseDTO.LoginResponseDTO loginedUser = userCommandService.login(loginRequest);
private final UserCommandService userCommandService;

HttpHeaders headers = new HttpHeaders();
headers.add("access", loginedUser.getAccessToken());
@PostMapping("/login")
public ResponseEntity<ApiResponse<AuthResponseDTO.UserInfoDTO>> login(
@RequestBody AuthRequestDTO.SocialLoginDTO loginRequest, HttpServletResponse response) {
AuthResponseDTO.LoginResponseDTO loginedUser = userCommandService.login(loginRequest);

Cookie refresh = Util.createCookie("refresh", loginedUser.getRefreshToken());
response.addCookie(refresh);
HttpHeaders headers = new HttpHeaders();
headers.add("access", loginedUser.getAccessToken());

return ResponseEntity.ok()
.headers(headers)
.body(ApiResponse.onSuccess(loginedUser.getUserInfo()));
}
Cookie refresh = Util.createCookie("refresh", loginedUser.getRefreshToken());
response.addCookie(refresh);

@PostMapping(value = "/join", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ApiResponse<AuthResponseDTO.UserInfoDTO>> join(
@RequestPart("joinRequest") UserRequestDTO.CreateUserDTO joinRequest,
@RequestPart(value = "petProfileImage", required = false) MultipartFile petProfileImage,
HttpServletResponse response) {
return ResponseEntity.ok()
.headers(headers)
.body(ApiResponse.onSuccess(loginedUser.getUserInfo()));
}

joinRequest.setPetProfileImage(petProfileImage);
@PostMapping(value = "/join", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ApiResponse<AuthResponseDTO.UserInfoDTO>> join(
@RequestPart("joinRequest") UserRequestDTO.CreateUserDTO joinRequest,
@RequestPart(value = "petProfileImage", required = false) MultipartFile petProfileImage,
HttpServletResponse response) {

joinRequest.setPetProfileImage(petProfileImage);

AuthResponseDTO.LoginResponseDTO joinedUser = userCommandService.join(joinRequest);
AuthResponseDTO.LoginResponseDTO joinedUser = userCommandService.join(joinRequest);

HttpHeaders headers = new HttpHeaders();
headers.add("access", joinedUser.getAccessToken());
HttpHeaders headers = new HttpHeaders();
headers.add("access", joinedUser.getAccessToken());

Cookie refresh = Util.createCookie("refresh", joinedUser.getRefreshToken());
response.addCookie(refresh);
Cookie refresh = Util.createCookie("refresh", joinedUser.getRefreshToken());
response.addCookie(refresh);

return ResponseEntity.ok()
.headers(headers)
.body(ApiResponse.onSuccess(joinedUser.getUserInfo()));
}
return ResponseEntity.ok()
.headers(headers)
.body(ApiResponse.onSuccess(joinedUser.getUserInfo()));
}

@PostMapping("/reissue")
public ResponseEntity<ApiResponse<String>> reissue(HttpServletRequest request, HttpServletResponse response) {
String refresh = null;

@PostMapping("/reissue")
public ResponseEntity<ApiResponse<String>> reissue(HttpServletRequest request, HttpServletResponse response) {
String refresh = null;
Cookie[] cookies = request.getCookies();

Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("refresh")) {
refresh = cookie.getValue();
}
}

for (Cookie cookie : cookies) {
if (cookie.getName().equals("refresh")) {
refresh = cookie.getValue();
}
}
AuthResponseDTO.ReissueResponseDTO reissued = userCommandService.reissue(refresh);

AuthResponseDTO.ReissueResponseDTO reissued = userCommandService.reissue(refresh);
response.setHeader("access", reissued.getAccessToken());
response.addCookie(Util.createCookie("refresh", reissued.getRefreshToken()));

response.setHeader("access", reissued.getAccessToken());
response.addCookie(Util.createCookie("refresh", reissued.getRefreshToken()));
return ResponseEntity.ok(ApiResponse.onSuccess("reissued"));

return ResponseEntity.ok(ApiResponse.onSuccess("reissued"));
}

}
@PostMapping("/logout")
public ResponseEntity<ApiResponse<String>> logout(HttpServletRequest request, HttpServletResponse response) {
String refreshToken = null;
Cookie[] cookies = request.getCookies();

@PostMapping("/logout")
public ResponseEntity<ApiResponse<String>> logout(HttpServletRequest request, HttpServletResponse response) {
String refreshToken = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("refresh")) {
refreshToken = cookie.getValue();
break;
}
}
}

if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("refresh")) {
refreshToken = cookie.getValue();
break;
}
}
}
userCommandService.logout(refreshToken);

userCommandService.logout(refreshToken);
// 클라이언트 쪽 쿠키 삭제
Cookie refreshCookie = new Cookie("refresh", null);
refreshCookie.setMaxAge(0);
refreshCookie.setPath("/");
response.addCookie(refreshCookie);

// 클라이언트 쪽 쿠키 삭제
Cookie refreshCookie = new Cookie("refresh", null);
refreshCookie.setMaxAge(0);
refreshCookie.setPath("/");
response.addCookie(refreshCookie);
return ResponseEntity.ok(ApiResponse.onSuccess("로그아웃 성공"));
}

return ResponseEntity.ok(ApiResponse.onSuccess("로그아웃 성공"));
}
@PostMapping("/duplicate")
public ApiResponse<String> checkDuplicate(@RequestBody @Valid UserRequestDTO.DuplicateCheckDTO duplicateCheckDTO) {
return ApiResponse.onSuccess(userCommandService.duplicateCheck(duplicateCheckDTO));
}
}


59 changes: 33 additions & 26 deletions src/main/java/com/petqa/dto/user/UserRequestDTO.java
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
package com.petqa.dto.user;

import java.time.LocalDate;

import org.springframework.web.multipart.MultipartFile;

import com.petqa.domain.enums.Gender;
import com.petqa.domain.enums.PetType;
import jakarta.annotation.Nullable;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;

public class UserRequestDTO {

@Data
public static class CreateUserDTO {
@NotNull(message = "반려동물 종류는 필수값입니다.")
private PetType petType;
@Data
public static class CreateUserDTO {
@NotNull(message = "반려동물 종류는 필수값입니다.")
private PetType petType;

@NotBlank(message = "소셜 ID는 필수값입니다.")
private String socialId;

@NotBlank(message = "소셜 ID는 필수값입니다.")
private String socialId;
@NotBlank(message = "사용자 닉네임은 필수값입니다.")
private String username;

@NotBlank(message = "사용자 닉네임은 필수값입니다.")
private String username;
@NotBlank(message = "반려동물 이름은 필수값입니다.")
private String petName;

@NotBlank(message = "반려동물 이름은 필수값입니다.")
private String petName;
@NotBlank(message = "반려동물의 생일은 필수값입니다.")
private LocalDate petBirthday;

@NotBlank(message = "반려동물의 생일은 필수값입니다.")
private LocalDate petBirthday;
@NotNull(message = "반려동물의 성별은 필수값입니다.")
private Gender petGender;

@NotNull(message = "반려동물의 성별은 필수값입니다.")
private Gender petGender;
private Double petWeight;

private Double petWeight;
private MultipartFile petProfileImage;

private MultipartFile petProfileImage;
}

}
@Getter
public static class CheckUsernameDuplicatedDTO {
@NotEmpty(message = "사용자 닉네임은 필수값입니다.")
private String username;
}

@Getter
public static class CheckUsernameDuplicatedDTO {
@NotEmpty(message = "사용자 닉네임은 필수값입니다.")
private String username;
}
@Getter
public class DuplicateCheckDTO {
@NotEmpty(message = "사용자 닉네임은 필수값입니다.")
private String username;
}
}
22 changes: 12 additions & 10 deletions src/main/java/com/petqa/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package com.petqa.repository;

import com.petqa.domain.User;
import io.lettuce.core.dynamic.annotation.Param;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findUserBySocialIdAndUsername(String socialId, String username);
import com.petqa.domain.User;

@Query("select u from User u join fetch u.pet where u.socialId = :socialId and u.username = :username")
Optional<User> findUserAndPetBySocialIdAndUsername(@Param("socialId") String socialId, @Param("username") String username);
import io.lettuce.core.dynamic.annotation.Param;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findUserBySocialIdAndUsername(String socialId, String username);

Optional<User> findByUsername(String username);
@Query("select u from User u join fetch u.pet where u.socialId = :socialId and u.username = :username")
Optional<User> findUserAndPetBySocialIdAndUsername(@Param("socialId") String socialId,
@Param("username") String username);

Optional<User> findById(Long userId);
Optional<User> findByUsername(String username);

Optional<User> findById(Long userId);

Optional<User> findUserByUsername(String username);
}
10 changes: 6 additions & 4 deletions src/main/java/com/petqa/service/user/UserCommandService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

public interface UserCommandService {

AuthResponseDTO.LoginResponseDTO login(AuthRequestDTO.SocialLoginDTO socialLoginDTO);
AuthResponseDTO.LoginResponseDTO login(AuthRequestDTO.SocialLoginDTO socialLoginDTO);

AuthResponseDTO.LoginResponseDTO join(UserRequestDTO.CreateUserDTO joinRequest);
AuthResponseDTO.LoginResponseDTO join(UserRequestDTO.CreateUserDTO joinRequest);

AuthResponseDTO.ReissueResponseDTO reissue(String refreshToken);
AuthResponseDTO.ReissueResponseDTO reissue(String refreshToken);

void logout(String refreshToken);
void logout(String refreshToken);

String duplicateCheck(UserRequestDTO.DuplicateCheckDTO duplicateCheckDTO);
}
Loading
Loading