LostCatBox

SpringProject-Board-CH08

Word count: 590Reading time: 3 min
2022/12/24 Share

Spring 게시판 프로젝트 8편 (refreshtoken 추가 및 기타 변경사항 적용 )

Created Time: August 3, 2022 1:30 PM
Last Edited Time: August 4, 2022 9:45 AM
References: https://sudo-minz.tistory.com/52

왜?

다음과 같이 변경사항들을 고쳐 보기로했다.

Vue

  • 회원가입, 로그인버튼 동시에 보이지 않도록하기
  • 댓글에 대한 권한 구현
  • 댓글구현에 대해서 블록별로 상속받고있는데, 이를 reload()를 블록별로하는게 아닌 window.location.reload()를 하여, vue의 장점을 못누리고있다. 다시 짜보자 찾아보고

Spring

  • x-auth-token 방식에서 authorization 방식으로 변경 “bearer” 토큰방식
  • 현재는 accesstoken만 사용하고있는데 refresh토큰까지 사용해보기
  • 전체적인 구조 다듬기
  • 응답 일관화 하기 JSON응답으로!!!
  • 응답시 응답 객체를 따로 만들지 고민해보기

authorization방식으로 변경

인증(Authentication)
사용자가 자신의 계정을 사용하려고 할 때 필요한 절차이고 암호화를 통해 이루어지며,

권한(Authorization)

사용자가 서비스를 이용할 때 서버가 로그인을 한 사용자를 인식하여 어떤 행위에 대한 허가를 내려주는 개념이죠.

권한에 대해 x-auth-token 방식에서 authorization으로 변경할려고함

왜?

https://stackoverflow.com/questions/69494662/x-auth-token-vs-x-access-token-vs-authorization-in-jwt

현재는 x-auth-token을 access token으로 활용하고있다. 하지만 x-auth-token은 표준화가 없고, 규칙이 따로없었다

authorization은 RFC의 표준화 절차 제공하는 문서에 정의 되어있다([RFC 6750](https://www.rfc-editor.org/rfc/rfc6750))

1
2
3
4
5
6
7
8
9
When sending the access token in the "Authorization" request header
field defined by HTTP/1.1 [RFC2617], the client uses the "Bearer"
authentication scheme to transmit the access token.

For example:

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM

back-end

  • JwtProvider
    • 기존방식 X-AUTH-TOKEN 방식에서 바꿔야하므로 다음과 같이 수정
    • 토큰값 앞에도 Bearer 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public String resolveToken(HttpServletRequest request) {
return request.getHeader("Authorization"); //기존방식 X-AUTH-TOKEN 방식에서 바꿔야하므로 다음과 같이 수정
}

public String createToken(String userPk, UserLoginResponseDto userLoginResponseDto) {

// user 구분을 위해 Claims에 User Pk값 넣어줌
Claims claims = Jwts.claims().setSubject(userPk); //클래임에 userPK 추가
claims.put("roles", userLoginResponseDto.getRoles()); //권한 추가
claims.put("email", userLoginResponseDto.getEmail());
claims.put("username", userLoginResponseDto.getEmail());
Date now = new Date(); // 생성날짜, 만료날짜를 위한 Date

String token = Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime() + tokenValidMillisecond))
.signWith(SignatureAlgorithm.HS256, secretKey) //secretKey, 암호화알고리즘
.compact();
return "Bearer " + token; //토큰값앞에도 Bearer 추가
}
  • JwtAuthenticationFilter
    • startswith(”Bearer “) 를 활용하여, 시작을 체크한다.!! 그후 substring으로 추출하여, 기존과같이 token값 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RequiredArgsConstructor
// SecurityConfig에서 userpassword filter보다 앞에 등록
public class JwtAuthenticationFilter extends GenericFilterBean {

private final JwtProvider jwtProvider;

// request로 들어오는 Jwt의 유효성을 검증 - JwtProvider.validationToken() 을 필터로서 FilterChain에 추가
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String requestTokenHeader = jwtProvider.resolveToken((HttpServletRequest) request); //http에서 Bearer+Token값 얻어옴(JWT토큰)
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) { // Bearer로 시작하는지확인
String token = requestTokenHeader.substring(7); //token값 추출
jwtProvider.validationToken(token);// validationToken()으로 secret key로 시그니처 일치확인 및 만료일자 지낫는지확인함
Authentication authentication = jwtProvider.getAuthentication(token); //token에서 get(userpk)하여 loadbyusername()실행하여, 해당 유저의 authentication 생성및반환
SecurityContextHolder.getContext().setAuthentication(authentication); // authentication
}
filterChain.doFilter(request, response);
}
}
  • SignController
    • Authorization 의 값으로 json 응답!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ApiOperation(value = "로그인", notes = "이메일로 로그인을 합니다.")
@PostMapping("/login")
public SingleResult<Map> login(
@ApiParam(value = "로그인 아이디 : 이메일", required = true) @RequestBody Map<String, String> loginMap) {
String email = loginMap.get("username");
String password = loginMap.get("password");
UserLoginResponseDto userLoginDto = userService.login(email, password);

String token = jwtProvider.createToken(String.valueOf(userLoginDto.getId()), userLoginDto);
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("Authorization", token);

return responseService.getSingleResult(tokenMap);
}

vue 에서 제공하는 페이지 새로고침 활용

기존에는 window.location.reload(true)사용했다. 하지만 이제 this.$route.go()를 적용하였다.

CATALOG
  1. 1. Spring 게시판 프로젝트 8편 (refreshtoken 추가 및 기타 변경사항 적용 )
  2. 2. 왜?
  3. 3. authorization방식으로 변경
    1. 3.1. 왜?
    2. 3.2. back-end
  4. 4. vue 에서 제공하는 페이지 새로고침 활용