Skip to content

Commit

Permalink
feat: Numble5#28 save UserInterest when save User entity
Browse files Browse the repository at this point in the history
  • Loading branch information
savannah030 committed Apr 26, 2022
1 parent 43bb663 commit 5070dbd
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 53 deletions.
74 changes: 42 additions & 32 deletions src/main/java/com/example/backend/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.example.backend.controller;

import com.example.backend.domain.dto.Message;
import com.example.backend.domain.user.User;
import com.example.backend.domain.user.dto.SignUpRequestDto;
import com.example.backend.domain.user.dto.SignUpResponseDto;
import com.example.backend.domain.user.dto.UserReponseDtoByCookie;
import com.example.backend.exception.BackendException;
import com.example.backend.exception.ReturnCode;
import com.example.backend.security.JwtAuthenticationFilter;
import com.example.backend.security.TokenProvider;
import com.example.backend.repository.UserRepository;
Expand All @@ -19,9 +19,7 @@
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;



@Slf4j
Expand All @@ -31,51 +29,63 @@
public class UserController {

private final UserService userService;
private final KakaoApiService kakaoApiService;
private final TokenProvider tokenProvider;
private final UserRepository userRepository;
private final JwtAuthenticationFilter jwtAuthenticationFilter;

// 시작하기 버튼을 눌러 회원가입을 완료한다
// 1. 이때 프론트에서 보내준 이메일로 jwt를 만들어 쿠키를 만들고, 응답에 추가한다.
// 2. signUpRequestDto으로 User 엔티티를 만든다.
// 1. signUpRequestDto으로 User 엔티티를 만든다.
// 2. 엔티티 잘 생성되었는지 확인
@PostMapping("/auth/register-submit")
public SignUpResponseDto signup(HttpServletResponse response, @RequestBody SignUpRequestDto signUpRequestDto) throws BackendException {

// 1.
Cookie cookie = new Cookie("access_token", tokenProvider.createJws(signUpRequestDto.getEmail()));
cookie.setMaxAge(7 * 24 * 60 * 60);
cookie.setSecure(true);
cookie.setHttpOnly(true);
response.addCookie(cookie);
// 2.
return userService.createUser(signUpRequestDto);
public ResponseEntity<?> signup(HttpServletResponse response, @RequestBody SignUpRequestDto signUpRequestDto) throws BackendException {

// 1
ReturnCode returnCode = userService.createUser(signUpRequestDto);

// 2-1. 이메일이 이미 있어서 서비스단에서 User 엔티티 만들기 실패했으면 잘못된 요청보냈다고 응답하기
if(returnCode != ReturnCode.SUCCESS){
return new ResponseEntity<>(new Message(ReturnCode.USER_EXIST_USING_THIS_EMAIL, null), HttpStatus.OK);
}
// 2-2. User 엔티티 저장한 결과 해당 이메일 갖는 엔티티가 한 개 뿐이라면
if(userRepository.existsOnlyByEmail(signUpRequestDto.getEmail())){

// User 엔티티의 List<userInterests>에 잘 저장되었는지 로그 찍어보기 //ok
User user = userRepository.findByEmail(signUpRequestDto.getEmail()).get();
user.getUserInterests().forEach(userInterest -> log.info("userInterest : {}", userInterest.toString()));

// 쿠키 만들고
Cookie cookie = new Cookie("access_token", tokenProvider.createJws(signUpRequestDto.getEmail()));
cookie.setMaxAge(7 * 24 * 60 * 60);
cookie.setSecure(true);
cookie.setHttpOnly(true);

// 응답 보내기
response.addCookie(cookie);
return new ResponseEntity<>(new Message(ReturnCode.SUCCESS, cookie.toString()), HttpStatus.OK);
}
// 2-3. 한개가 아니라 0개거나 2개 이상이면 내부 서버 오류 응답
return new ResponseEntity<>(new Message(ReturnCode.INTERNAL_SERVER_ERROR, null), HttpStatus.OK);
}

// 쿠키정보 보내면 회원정보 리턴(사용자 인증용)
@GetMapping("/auth/check")
public UserReponseDtoByCookie getUserInfoByCookie(HttpServletRequest request){

// TODO: 쿠키 3.5일 이하로 남았으면 쿠키 다시 보내기
// Arrays.stream(request.getCookies()).filter(cookie -> cookie.getMaxAge())
public ResponseEntity<?> getUserInfoByCookie(HttpServletRequest request){

String accessToken = jwtAuthenticationFilter.parseCookie(request);

log.info("accessToken getUserInfoByCookie: {}",accessToken);
String email = tokenProvider.getEmailfromJwt(accessToken);
Optional<User> user = userRepository.findByEmail(email);
// 엔티티 객체 없으면 null 리턴
// 있으면 그 객체의 필드로 dto 초기화
return user.map(UserReponseDtoByCookie::new).orElse(null);
if(accessToken==null){
return new ResponseEntity<>(new Message(ReturnCode.NO_COOKIE, null), HttpStatus.OK);
}
return userService.getUserInfoByJwt(accessToken);
}

// 닉네임 중복검사
@GetMapping("/auth/check/{nickname}")
public Boolean checkNickname(@PathVariable("nickname") String nickname){
public ResponseEntity<?> checkNickname(@PathVariable("nickname") String nickname){
log.info("/auth/check/{nickname} : {}",nickname);
if(userRepository.existsByNickname(nickname)){
return true;
return new ResponseEntity<>(new Message(ReturnCode.USER_EXIST_USING_THIS_NICKNAME, null), HttpStatus.OK);
}
return false;
return new ResponseEntity<>(new Message(ReturnCode.SUCCESS, nickname), HttpStatus.OK);
}

// NOTE: JWT 기반 로그인은 모든 요청마다 사용자를 검증하는 방식으로 구현함 (세션과의 차이점)
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/example/backend/domain/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class User extends BaseEntity {
@Column(name = "user_idx")
private Long idx;

@Column(nullable = false)
//@Column(nullable = false)
private String email;
private String nickname;

Expand All @@ -41,7 +41,7 @@ public class User extends BaseEntity {
private Profile profile;

@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<UserInterest> interests = new LinkedList<>();
private List<UserInterest> userInterests = new LinkedList<>();

@OneToMany(mappedBy = "uploader", fetch = FetchType.LAZY)
private List<Video> myVideos = new LinkedList<>();
Expand All @@ -56,8 +56,10 @@ public User(String email, String nickname, RoleType roleType, UserStatus status,
this.profile = profile;
}

public void addInterest(UserInterest userInterest){
this.interests.add(userInterest);

// 관심사 추가
public void addInterests(List<UserInterest> userInterests){
this.userInterests = userInterests;
}

public void addMyVideo(Video myVideo){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.backend.domain.user;

import com.example.backend.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -22,4 +23,10 @@ public class UserInterest extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "interest_idx")
private Interest interest;

public UserInterest(User user, Interest interest) {
this.user = user;
this.interest = interest;
}

}
87 changes: 70 additions & 17 deletions src/main/java/com/example/backend/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.example.backend.service;

import com.example.backend.domain.dto.Message;
import com.example.backend.domain.user.Interest;
import com.example.backend.domain.user.User;
import com.example.backend.domain.user.UserInterest;
import com.example.backend.domain.user.dto.SignUpRequestDto;
import com.example.backend.domain.user.dto.SignUpResponseDto;
import com.example.backend.domain.user.dto.UserReponseDtoByCookie;
import com.example.backend.exception.ReturnCode;
import com.example.backend.repository.InterestRepository;
import com.example.backend.repository.UserInterestRepository;
import com.example.backend.security.TokenProvider;
import com.example.backend.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;


@Slf4j
Expand All @@ -26,32 +30,81 @@ public class UserService {

private final UserRepository userRepository;
private final TokenProvider tokenProvider;
private final InterestRepository interestRepository;
private final UserInterestRepository userInterestRepository;

// User 엔티티 만들고 레포지토리에 저장
// 1. signUpDto를 User 엔티티로 변환
// 2. 관심사 추가
// 3. 레포지토리에 저장
// 1. 해당 이메일을 갖는 User 엔티티가 이미 있으면(0개 초과이면) 400 에러
// 2. signUpDto를 User 엔티티로 변환
// 3. 관심사 추가
// 4. 레포지토리에 저장
@Transactional
public SignUpResponseDto createUser(SignUpRequestDto signUpRequestDto){
public ReturnCode createUser(SignUpRequestDto signUpRequestDto){

// 1.
if (userRepository.existsByEmail(signUpRequestDto.getEmail())){
return ReturnCode.USER_EXIST_USING_THIS_EMAIL;
}

// 2.
User user = signUpRequestDto.toEntity(); // 1.
// TODO: 2. 관심사 추가
userRepository.save(user); //3.
return SignUpResponseDto.builder()
.nickname(user.getNickname())
.status(200).build();
log.info("email: {}", user.getEmail());
log.info("nickname: {}", user.getNickname());
log.info("age: {}", user.getUserInfo().getAge());
log.info("gender: {}", user.getUserInfo().getGenderType());
log.info("city: {}", user.getUserInfo().getCity());
log.info("district: {}", user.getUserInfo().getDistrict());

// 3. 관심사 추가
// 3-1. 프론트에서 받아온 관심사 문자열이 모두 Interest 테이블에 있는지 확인
List<String> interestStr = signUpRequestDto.getSelectedInterests();
List<Interest> interests = new LinkedList<>();
for(String i: interestStr){
Optional<Interest> interest = interestRepository.findByInterestName(i);
if (!interest.isPresent()){
return ReturnCode.INVALID_INTEREST;
}
interests.add(interest.get());
}

// 3-2. UserInterest 엔티티 저장하고 User에 저장하기 위해 리스트에 추가
List<UserInterest> userInterests = new LinkedList<>();
for(Interest interest: interests){
// userInterest 객체 생성해서 레포지토리에 저장
UserInterest userInterest = new UserInterest(user,interest);
userInterestRepository.save(userInterest);
userInterests.add(userInterest);
}
// 양방향 관계 저장
user.addInterests(userInterests);

// 4.
userRepository.save(user);
return ReturnCode.SUCCESS;

}

// 1. 해당 이메일을 갖는 User 엔티티가 없으면 회원가입(step1으로 이동)
// 2. User 엔티티가 없으면 로그인(메인 페이지로 이동)
public Boolean alreadySignUp(String email){
if(userRepository.existsByEmail(email)){
if(userRepository.existsOnlyByEmail(email)){
return true;
}
return false;
}

public ResponseEntity<?> getUserInfoByJwt(String accessToken){
String email = tokenProvider.getEmailfromJwt(accessToken);
if(email.equals("forged")){
return new ResponseEntity<>(new Message(ReturnCode.INVALID_COOKIE,null), HttpStatus.OK);
}
Optional<User> user = userRepository.findByEmail(email);
// 엔티티 객체 없으면 있으면 유저정보 리턴
// 없으면 null 리턴
if (user.isPresent()){
return new ResponseEntity<>(new Message(ReturnCode.SUCCESS, new UserReponseDtoByCookie(user.get())), HttpStatus.OK);
}
return new ResponseEntity<>(new Message(ReturnCode.INTERNAL_SERVER_ERROR, null), HttpStatus.OK);
}

}

0 comments on commit 5070dbd

Please sign in to comment.