Skip to content

Commit

Permalink
⚽feat#23: [Auth2] refresh Token 생성, 회원가입, AccessToken재발급
Browse files Browse the repository at this point in the history
  • Loading branch information
Juhyeok0202 committed Jul 26, 2023
1 parent 35a0121 commit 921e7a8
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
import com.umc.DongnaeFriend.global.exception.CustomException;
import com.umc.DongnaeFriend.global.exception.ErrorCode;
import com.umc.DongnaeFriend.global.util.JwtTokenProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

@Autowired
Expand All @@ -25,22 +27,25 @@ public class UserController {

JwtTokenProvider jwtTokenProvider;



/**
* 유저 로그인 / 회원가입
* 인증 절차
*/
@PostMapping("/login")
public ResponseEntity<?> userLogin(@RequestBody UserDto.Request request) {
try {
log.info("userLogin 진입");
//사용자 정보 가져오기
HashMap<String, Object> userInfo = kakaoService.getUserInfo(request.getAccessToken());

//사용자 확인 기존 회원 -> 넘어가고, 없는 회원 -> 회원가입
userService.userValidation(userInfo);

//토큰 생성
String access_token = jwtTokenProvider.createAccessToken((Long) userInfo.get("usreId"));

String access_token = jwtTokenProvider.createAccessToken((Long) userInfo.get("userId"));
log.info("access_token : {}", access_token);
return ResponseEntity.ok(access_token);

} catch (IOException e) {
Expand All @@ -49,8 +54,16 @@ public ResponseEntity<?> userLogin(@RequestBody UserDto.Request request) {
}

@PostMapping("/user/reissuance")
public ResponseEntity<?> reiussnaceToken(String access_oto) {
return null;
public ResponseEntity<?> reiussnaceToken(String refreshToken) {
try {

//토큰 재발급
String access_token = userService.createAccessTokenFromRefreshToken(refreshToken);
return ResponseEntity.ok(access_token);
} catch (Exception e) {
// RefreshToken만료
throw new CustomException(ErrorCode.INVALID_REFRESH_TOKEN);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findById(Long id);

Optional<User> findByRefreshToken(String refresh_token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,33 @@
import com.umc.DongnaeFriend.domain.type.Age;
import com.umc.DongnaeFriend.domain.type.Gender;
import com.umc.DongnaeFriend.domain.type.YesNo;
import com.umc.DongnaeFriend.domain.user.dto.UserDto;
import com.umc.DongnaeFriend.domain.user.entity.User;
import com.umc.DongnaeFriend.domain.user.repository.UserRepository;
import com.umc.DongnaeFriend.global.exception.CustomException;
import com.umc.DongnaeFriend.global.exception.ErrorCode;
import com.umc.DongnaeFriend.global.util.JwtTokenProvider;
import com.umc.DongnaeFriend.global.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Optional;

@Service
@Slf4j
public class UserService {

@Autowired
UserRepository userRepository;

KakaoService kakaoService;

JwtTokenProvider jwtTokenProvider;

public void userValidation(HashMap<String, Object> userInfo) {
Optional<User> user= userRepository.findById((Long) userInfo.get("userId"));

if (user.isEmpty()) {
userRegister(userInfo);
}
Expand All @@ -37,23 +44,51 @@ public void userRegister(HashMap<String, Object> userInfo) {
String email = userInfo.get("email").toString();

Optional<String> gender = Optional.ofNullable(userInfo.get("gender").toString());
String strGender = "";
log.info("Gender : {}", gender.get());
if(gender.get()=="F"){
strGender="여성";
}else {
strGender = "남성";
}
log.info("strGender : {}", strGender);


Optional<String> age = Optional.ofNullable(userInfo.get("age").toString());
String[] ageRange = age.get().split("-");


// refreshToken userId를 claim 으로 생성 뒤, User의 필드에 넣고 User를 저장
String refresh_Token = jwtTokenProvider.createRefreshToken((Long) userInfo.get("usreId"));

userRepository.save(
User.builder()
.nickname(nickName)
.email(email)
//TODO : Gender 결정
.gender(Gender.FEMALE)
//TODO : Age 결정
.age(Age.AGE10)
//TODO : Gender 결정[O]
.gender(Gender.valueOf(strGender))
//TODO : Age 결정[O]
.age(Age.valueOf(ageRange[0]+"대"))
.townCert(YesNo.NO)
.townCertCnt(0)
.infoCert(YesNo.NO)
.refreshToken(refresh_Token)
.build()
);
}

// RefreshToken으로 AccessToken 재발급
public String createAccessTokenFromRefreshToken(String refreshToken) {
String accessToken = "";

// 전달받은 RefreshToken 정보로 사용자 조회(유효하지 않은 토큰일 시, 예외 발생)
Optional<User> userByRefreshToken =Optional.ofNullable(userRepository.findByRefreshToken(refreshToken)
.orElseThrow(()-> new CustomException(ErrorCode.INVALID_REFRESH_TOKEN,"해당 refreshToken 이 존재하지 않음")));

// AccessToken 재발행
accessToken = jwtTokenProvider.createAccessToken(userByRefreshToken.get().getId());
log.info("AcessToken 재발행 성공");

return accessToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import javax.persistence.Id;
import java.util.Date;

import static com.umc.DongnaeFriend.config.JwtConfig.SECRET_KEY;
Expand Down Expand Up @@ -46,6 +47,18 @@ public String createAccessToken(Long userId) {
.compact();
}

// RefreshToken 생성
public String createRefreshToken(Long userId) {
Date now = new Date();
Date validity = new Date(now.getTime() + REFRESH_TOKEN_EXPIRE_LENGTH);

return Jwts.builder()
.signWith(SignatureAlgorithm.ES512, String.valueOf(SECRET_KEY))
.claim("userId", userId)
.setIssuedAt(now)
.setExpiration(validity)
.compact();
}



Expand Down
17 changes: 15 additions & 2 deletions src/main/java/com/umc/DongnaeFriend/security/JwtTokenFilter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.umc.DongnaeFriend.security;

import com.umc.DongnaeFriend.global.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
Expand All @@ -11,20 +13,27 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
@Slf4j
public class JwtTokenFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

log.info("JwtTOkenFilter 진입");

// Request Header에서 JWT 토큰 가져오기
String authorizationHeader = request.getHeader("Authorization");
log.info("authorizationHeader : {}",authorizationHeader);

// JWT 토큰이 "Bearer "로 시작하는지 확인하고 토큰 추출
//🛑 첫 로그인 시에도 이곳에서 걸리기 때문에 로그인이 안됨.(null)
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);

log.info("token : {}",token);
try {
// JWT 토큰 검증
JwtUtil.validateToken(token);
log.info("JWT 토큰 검증완료");

// JWT 토큰에서 사용자 정보 추출 (예: 사용자 ID)
Long userId = JwtUtil.getUserIdFromToken(token);
Expand All @@ -35,7 +44,11 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse

// SecurityContextHolder에 인증 객체 저장
SecurityContextHolder.getContext().setAuthentication(authenticationToken);


} catch (Exception e) {
log.info("예외발생");

// JWT 토큰 검증 실패 시, 인증 객체를 null로 설정
SecurityContextHolder.clearContext();
}
Expand Down

0 comments on commit 921e7a8

Please sign in to comment.