[Spring-boot]JWT를 이용해 AccessToken 발급, 검사, 정보 추출

2023. 6. 12. 00:41·Backend/Spring
반응형
JWT(Json Web Token)이란?
사용자 인증을 위해 인증에 필요한 정보를 토큰에 담아서 암호화시켜 사용하는 인터넷 표준 인증 방식

1. JWT란?

JWT는 Header, Payload, Signature 3 부분으로 구성되어 있다. 

  • Header : Header에는 JWT의 유형과 해시 알고리즘 등의 메타 데이터를 포함한다.
    • 보통 "typ" , "alg" 가 들어가고, JSON형식으로 표현되고, Base64로 인코딩 됩니다.
  • Payload : Payload는 Claim 정보를 포함합니다.
    • Claim은 토큰에 대한 추가적인 데이터를 나타냅니다. JSON 형식으로 표현되며, Base64로 인코딩 됩니다.
  • Signature : Signature은 헤더와 페이로드의 내용을 바탕으로 생성되며, 토큰이 유효하고 변경되지 않았음을 검증하는 역할을 합니다.

2. 코드

1. Build.gradle

	implementation 'io.jsonwebtoken:jjwt-api:0.11.1'
	runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.1', 'io.jsonwebtoken:jjwt-jackson:0.11.1'

Spring boot에서 JWT(Json Web Token)을 이용하기 위해 build.gradle에 위의 코드를 추가시켰다.

 

2. CreateToken(JwtTokenProvider)

	public String createAccessToken(String snsId) {
		Claims claims = Jwts.claims().setSubject("accessToken");
		claims.put("snsId", snsId); // 사용자를 식별하기 위한 값을 넣어주시면 됩니다.
		Date currentTime = new Date();

		return Jwts.builder()
			.setClaims(claims)
			.setIssuedAt(currentTime)
			.setExpiration(new Date(currentTime.getTime() + accessTokenValidTime))
			.signWith(SignatureAlgorithm.HS256, Base64Utils.encodeToString(JWT_SECRET_KEY.getBytes()))
			.compact();
	}

JwtTokenProvider에서 createAccessToken 메소드를 통해 토큰을 만들었다.

밑의 값이 들어간다. snsId의 Value에는 사용자의 snsId 값이 들어간다.

{
  "header": {
    "alg": "HS256",
    "typ": "JWT"
  },
  "payload": {
    "sub": "accessToken",
    "snsId": "<value>",
    ...
  },
  "signature": "<signature>"
}

 

3. ValidateToken(JwtTokenProvider)

	public Boolean validateAccessToken(String token) {
		try {
			Jwts.parserBuilder()
				.setSigningKey(Base64Utils.encodeToString(JWT_SECRET_KEY.getBytes()))
				.build()
				.parseClaimsJws(token).getBody();
			return true;
		} catch (ExpiredJwtException e) {
			throw new CustomException(HttpStatus.UNAUTHORIZED, "토큰이 만료 됐습니다.");
		} catch (UnsupportedJwtException e) {
			throw new CustomException(HttpStatus.BAD_REQUEST, "토큰을 지원 안합니다.");
		} catch (Exception e) {
			// 여기에서 예외 메시지를 설정해야 합니다.
			throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "토큰 검증 중에 오류가 발생했습니다.");
		}
	}

미리 정해놓은 SecretKey로 복호화를 한 뒤, ParseClaimsJws에서 토큰 유효성 검사를 한 뒤, 토큰에 문제가 있으면 에러를 반환합니다. 에러가 없다면 True를 반환합니다. (Filter과 연관이 있습니다)

    Jws<Claims> parseClaimsJws(String claimsJws)
        throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException;

 

4. ResolveToken(JwtTokenProvider)

	private String retrieveToken(HttpServletRequest request) {
		String bearerToken = request.getHeader("Authorization");
		if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
			return bearerToken.substring(7);
		}
		return null;
	}

Client가  Server에게 보내는 HttpServletRequest에서 Token값을 추출하는 과정입니다.

request의 header가 Authorization이거나 Bearer이면 Token을 추출합니다.

 

5. Get~~(JwtTokenProvider)

	public UsernamePasswordAuthenticationToken getAuthentication(String token) {
		//@AuthenticationPrincipal에서 필요한 정보 여기에 담기
		String snsId = getsnsIdFromToken(token);
		Member member = memberRepository.findBySnsId(snsId)
			.orElseThrow(() -> new RuntimeException("Member 를 찾지 못했습니다."));
		MemberPrincipal memberPrincipal = new MemberPrincipal(member);
		return new UsernamePasswordAuthenticationToken(memberPrincipal, token,
			member.getAuthorities());
	}

	//Token으로부터 snsId 추출
	public String getsnsIdFromToken(String token) {
		return Jwts.parserBuilder()
			.setSigningKey(Base64Utils.encodeToString(JWT_SECRET_KEY.getBytes()))
			.build().parseClaimsJws(token)
			.getBody()
			.get("snsId",
				String.class);
	}

Token에 저장되어 있는 각종 정보들을 get 하는 함수들입니다.

 

전체 코드

https://github.com/Chat-ITC/WITH_Server/tree/main/src/main/java/codingFriends_Server/global/auth/jwt

 

반응형
'Backend/Spring' 카테고리의 다른 글
  • LazyInitializationException이란? [트러블슈팅]
  • [Spring-boot] Spring Security 인증 인가
  • [Spring-boot] Redis를 활용한 RefreshToken 저장 및 조회
  • [POSTMAN] 쿠키 설정 및 확인하기
코딩하는_대학생
코딩하는_대학생
Java Developer, Open Source Enthusiast, Proud Son
  • 코딩하는_대학생
    코딩하는 대학생에서 개발자까지
    코딩하는_대학생
  • 전체
    오늘
    어제
    • 분류 전체보기 (218)
      • 코딩하는 대학생의 책 추천 (8)
        • 클린코드 (5)
        • 헤드퍼스트 디자인패턴 (3)
      • Backend (8)
        • Spring (14)
        • AWS (3)
        • 회고 (4)
        • Redis (5)
        • 다양한 시각에서 바라본 백엔드 (3)
      • Python (35)
        • 개념 및 정리 (15)
        • 백준 문제풀이 (20)
      • JAVA (17)
        • 개념 및 정리 (14)
        • 백준 문제풀이 (2)
      • 왜? (7)
      • C언어 (42)
        • 개념 및 정리 (9)
        • 백준 문제풀이 (32)
      • 개인 공부 (27)
        • 대학 수학 (5)
        • 대학 영어 (10)
        • 시계열데이터 처리 및 분석 (5)
        • 컴퓨터 네트워크 (6)
        • 운영체제 (1)
      • 솔직 리뷰 (23)
        • 꿀팁 (6)
        • IT기기 (1)
        • 국내 여행 (7)
        • 맛집 (2)
        • 알바 리뷰 (2)
      • 대외활동 (17)
        • 체리피우미 3기 (4)
        • 꿀잠이들 6기 (13)
      • 음식 평가 (1)
      • 일상 & 근황 (2)
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩하는_대학생
[Spring-boot]JWT를 이용해 AccessToken 발급, 검사, 정보 추출
상단으로

티스토리툴바