Skip to content

Commit

Permalink
Feat: Add refresh controller v1(#68, #69)
Browse files Browse the repository at this point in the history
  • Loading branch information
eastmeet committed Jan 20, 2023
1 parent 5743cbd commit 320c707
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
import com.main36.picha.domain.member.entity.Member;
import com.main36.picha.domain.member.mapper.MemberMapper;
import com.main36.picha.domain.member.service.MemberService;
import com.main36.picha.global.authorization.dto.RenewTokenDto;
import com.main36.picha.global.authorization.dto.TokenDto;
import com.main36.picha.global.authorization.filter.JwtProvider;
import com.main36.picha.global.authorization.jwt.JwtTokenizer;
import com.main36.picha.global.authorization.resolver.ClientId;
import com.main36.picha.global.authorization.userdetails.AuthMember;
import com.main36.picha.global.response.DataResponseDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -17,9 +22,12 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.Positive;

import static com.main36.picha.global.authorization.filter.JwtVerificationFilter.BEARER_PREFIX;

@Slf4j
@RestController
@Validated
Expand All @@ -29,6 +37,8 @@ public class MemberController {
private final MemberService memberService;

private final MemberMapper mapper;
private final JwtProvider jwtProvider;
private final JwtTokenizer jwtTokenizer;

@PostMapping("/signup")
public ResponseEntity<DataResponseDto<?>> postMember(@Valid @RequestBody MemberDto.Post memberPostDto) {
Expand Down Expand Up @@ -67,6 +77,35 @@ public ResponseEntity<?> getToken(@RequestParam String access_token,
// return ResponseEntity.ok(tokenBuilder);
}

@GetMapping("/renew/{member-id}")
public ResponseEntity<?> getToken(@PathVariable("member-id") Long memberId,
HttpServletRequest request) {
//TODO header에서 리프레쉬 토큰 뽑아내기
jwtProvider.validateToken(request.getHeader("refresh"));
Member memberByClientId = memberService.findMemberByMemberId(memberId);
AuthMember authMember = AuthMember.of(memberByClientId);
TokenDto tokenDto = jwtProvider.generateTokenDto(authMember);
String at = BEARER_PREFIX + tokenDto.getAccessToken();

RenewTokenDto builder = RenewTokenDto.builder()
.memberId(authMember.getMemberId())
.email(authMember.getEmail())
.accessToken(at)
.accessTokenExpiresIn(tokenDto.getAccessTokenExpiresIn())
.build();

return ResponseEntity.ok(new DataResponseDto<>(builder));

// 2. 토큰 엔티티에 담아 보내기
// Token tokenBuilder =
// Token.builder()
// .accessToken(at)
// .refreshToken(refresh_token)
// .build();
// return ResponseEntity.ok(tokenBuilder);
}


@PatchMapping("/users/edit/{member-id}")
public ResponseEntity<DataResponseDto<?>> patchMember(@ClientId Long clientId,
@PathVariable("member-id") @Positive Long memberId,
Expand All @@ -76,9 +115,7 @@ public ResponseEntity<DataResponseDto<?>> patchMember(@ClientId Long clientId,
memberPatchDto.setMemberId(memberId);
Member member = memberService.updateMember(mapper.memberPatchDtoToMember(memberPatchDto));

return new ResponseEntity<>(
new DataResponseDto<>(mapper.memberToProfileHomeDto(member)),
HttpStatus.OK);
return ResponseEntity.ok(new DataResponseDto<>(mapper.memberToProfileHomeDto(member)));
}

@GetMapping("/users/profile/{member-id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public class PostController {
private final MemberService memberService;
private final AttractionService attractionService;

@PostMapping("/register/{attraction-id}")
public ResponseEntity<DataResponseDto<?>> registerPost(@ClientId Long clientId,
@PostMapping("/register/{member-id}/{attraction-id}")
public ResponseEntity<DataResponseDto<?>> registerPost(@PathVariable("member-id") @Positive long memberId,
// @ClientId Long clientId,
@PathVariable("attraction-id") @Positive long attractionId,
@Valid @RequestBody PostDto.Post postRegisterDto) {
Post.PostBuilder postBuilder = Post.builder();
Expand All @@ -48,7 +49,7 @@ public ResponseEntity<DataResponseDto<?>> registerPost(@ClientId Long clientId,
.postTitle(postRegisterDto.getPostTitle())
.postContent(postRegisterDto.getPostContent())
.hashTagContent(postRegisterDto.getHashTagContent())
.member(memberService.findMemberByMemberId(clientId))
.member(memberService.findMemberByMemberId(memberId))
.attraction(attractionService.findAttraction(attractionId))
.comments(new ArrayList<>())
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@
import lombok.Builder;
import lombok.Data;

import java.util.List;

@Data
@Builder
public class LoginResponseDto {

private Long memberId;
private String email;
private String roles;
private String accessToken;

@Builder
public LoginResponseDto(Long memberId, String email, String roles) {
public LoginResponseDto(Long memberId, String email, String roles, String accessToken) {
this.memberId = memberId;
this.email = email;
this.roles = roles;
this.accessToken = accessToken;
}

public static LoginResponseDto of(AuthMember authMember){
@Builder
public static LoginResponseDto of(AuthMember authMember, String accessToken){
return LoginResponseDto.builder()
.memberId(authMember.getMemberId())
.email(authMember.getEmail())
.roles(authMember.getRoles().get(0))
.accessToken(accessToken)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.main36.picha.global.authorization.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RenewTokenDto {

private Long memberId;
private String email;
private String accessToken;
private Long accessTokenExpiresIn;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public class TokenDto {
private String accessToken;
private String refreshToken;
private Long accessTokenExpiresIn;

}

Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,33 @@
import com.main36.picha.global.authorization.dto.TokenDto;
import com.main36.picha.global.authorization.userdetails.AuthMember;
import com.main36.picha.global.response.DataResponseDto;
import com.main36.picha.global.utils.ErrorResponder;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;

import static com.main36.picha.global.authorization.filter.JwtVerificationFilter.BEARER_PREFIX;


@Slf4j

public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private final TokenProvider tokenProvider;
private final JwtProvider jwtProvider;
private final AuthenticationManager authenticationManager;

public JwtAuthenticationFilter(TokenProvider tokenProvider, AuthenticationManager authenticationManager) {
this.tokenProvider = tokenProvider;
public JwtAuthenticationFilter(JwtProvider jwtProvider, AuthenticationManager authenticationManager) {
this.jwtProvider = jwtProvider;
this.authenticationManager = authenticationManager;
}

Expand All @@ -60,43 +57,42 @@ protected void successfulAuthentication(HttpServletRequest request,

// Detail 문제로 -> 삽입 x
AuthMember authMember = (AuthMember) authResult.getPrincipal();
TokenDto tokenDto = tokenProvider.generateTokenDto(authMember);
TokenDto tokenDto = jwtProvider.generateTokenDto(authMember);
String accessToken = tokenDto.getAccessToken(); // accessToken 만들기
String refreshToken = tokenDto.getRefreshToken(); // refreshToken 만들기

// response 토큰 설정
ResponseCookie cookie = getResponseCookie(refreshToken);

response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
// response.setCharacterEncoding("utf-8");
response.setHeader("Set-Cookie", cookie.toString());
response.setHeader("Authorization", "Bearer " + accessToken);
response.setHeader("Authorization", BEARER_PREFIX + accessToken);

Gson gson = new Gson();
LoginResponseDto of = LoginResponseDto.of(authMember);
LoginResponseDto of = LoginResponseDto.of(authMember, BEARER_PREFIX + accessToken );
response.getWriter().write(gson.toJson(new DataResponseDto<>(of), DataResponseDto.class));
this.getSuccessHandler().onAuthenticationSuccess(request, response, authResult);



//tokenProvider.refreshTokenSetHeader(refreshToken,response); // RefreshToken Header response 생성

// login 완료시 Response 응답 만들기
// login 완료시 Response 응답 만들기

// // 로그인 성공시 Refresh Token Redis 저장 ( key = Refresh Token / value = Access Token )
// int refreshTokenExpirationMinutes = tokenProvider.getRefreshTokenExpirationMinutes();
// redisDao.setValues(refreshToken,accessToken, Duration.ofMinutes(refreshTokenExpirationMinutes));
// redisDao.setValues(refreshToken,accessToken, Duration.ofMinutes(refreshTokenExpirationMinutes));


}

private static ResponseCookie getResponseCookie(String refreshToken) {
ResponseCookie cookie = ResponseCookie.from("refreshToken", refreshToken)
.maxAge(3 * 24 * 60 * 60)

return ResponseCookie.from("refreshToken", refreshToken)
.maxAge(3 * 24 * 60 * 60) // 쿠키 유효기간 설정 (3일)
.path("/")
.secure(true)
.sameSite("None")
.httpOnly(true)
.sameSite("None")
.build();
return cookie;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,33 @@
import com.main36.picha.domain.refreshToken.exception.*;
import com.main36.picha.global.authorization.dto.TokenDto;
import com.main36.picha.global.authorization.userdetails.AuthMember;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Encoders;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;

import static com.main36.picha.global.authorization.filter.JwtVerificationFilter.BEARER_TYPE;

@Slf4j
@Component
@RequiredArgsConstructor

public class TokenProvider {
public class JwtProvider {
/* 유저 정보로 JWT 토큰을 만들거나 토큰을 바탕으로 유저 정보를 가져옴
* JWT 토큰 관련 암호화, 복호화, 검증 로직
*/

private static final String BEARER_TYPE = "bearer";


@Getter
@Value("${jwt.secret-key}")
Expand Down Expand Up @@ -137,7 +130,6 @@ public Authentication getAuthentication(String accessToken) {
authorities);

auth.getRoles().stream().forEach(authMember -> log.info("# AuthMember.getRoles 권한 체크 = {}", authMember));
// auth.getAuthorities().stream().forEach(a -> log.info("# auth.getAuthorities 권한 체크 = {}",a));

return new UsernamePasswordAuthenticationToken(auth, null, auth.getAuthorities());
}
Expand Down Expand Up @@ -180,4 +172,18 @@ public Claims parseClaims(String token) {
.getBody();
}

// public String getUsername(HttpServletRequest request) {
// String authorization = request.getHeader("authorization");
// String substring = authorization.substring(7);
// String secretKey = this.getSecretKey();
// Jws<Claims> claims = this.getClaims(substring,
// this.encodeBase64SecretKey(secretKey));
//
// return String.valueOf(claims.getBody().get("username"));
// }
// public Long getUserId(HttpServletRequest request) {
// Member member = memberService.findMemberByMemberEmail( getUsername(request));
//
// return member.getMemberId();
// }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.main36.picha.global.authorization.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.main36.picha.global.authorization.filter.TokenProvider;
import com.main36.picha.global.exception.BusinessLogicException;
import com.main36.picha.global.response.ErrorResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -25,7 +24,8 @@ public class JwtVerificationFilter extends OncePerRequestFilter {

private static final String AUTHORIZATION_HEADER = "Authorization";
public static final String BEARER_PREFIX = "Bearer ";
private final TokenProvider tokenProvider;
public static final String BEARER_TYPE = "bearer";
private final JwtProvider jwtProvider;


// 인증에서 제외할 url
Expand All @@ -52,9 +52,9 @@ protected void doFilterInternal(HttpServletRequest request,
String jwt = resolveToken(request);

// 토큰 검증을 통과하면 다음 필터 진행
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
if (StringUtils.hasText(jwt) && jwtProvider.validateToken(jwt)) {
// 토큰으로부터 Authentication 객체를 만듬
Authentication authentication = tokenProvider.getAuthentication(jwt);
Authentication authentication = jwtProvider.getAuthentication(jwt);

log.info("# Token verification success !");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
package com.main36.picha.global.authorization.handler;

import com.google.gson.Gson;
import com.main36.picha.domain.member.entity.Member;
import com.main36.picha.domain.member.mapper.MemberMapper;
import com.main36.picha.domain.refreshToken.entity.RefreshToken;
import com.main36.picha.domain.refreshToken.repository.RefreshTokenRepository;
import com.main36.picha.global.authorization.dto.LoginDto;
import com.main36.picha.global.authorization.dto.LoginResponseDto;
import com.main36.picha.global.authorization.dto.TokenDto;
import com.main36.picha.global.authorization.filter.TokenProvider;
import com.main36.picha.global.authorization.jwt.JwtTokenizer;
import com.main36.picha.global.authorization.resolver.ClientId;
import com.main36.picha.global.authorization.userdetails.AuthMember;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
Expand All @@ -22,9 +11,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Slf4j
Expand Down
Loading

0 comments on commit 320c707

Please sign in to comment.