본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Spring framework/Spring boot

Spring JWT 를 활용한 로그인

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 11. 19.

 

프론트프레임워크(라이브러리)인 앵귤러, 리엑트 및 뷰js등의 기능이 이제 슬슬 대세가 되는 것 같습니다.

이러한 프론트프레임워크(라이브러리)는 SPA 방식(Single Page Application) 이기 때문에 페이지 로딩을 위해 최초 1회만 서버에 요청할 뿐 그 이후에는 데이터에 대한 CRUD 요청만 보내게 됩니다.

 

이러한 프론트 프레임워크에서의 기술에서 로그인과 관련된 내용을 좀 더 쉽게 구현하기 위해서는 서버에서의 세션(SESSION)보다는 특정 암호화된 키 값을 활용한 json web token 방식(JWT)이 좀 더 낫다고 생각 합니다.

 

JWT를 사용하기 위해서는 먼저 라이브러리 2개를 받아 줍니다.

* gradle 기준

implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'

 

* maven 기준

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

 

자바에서 제공되는 JWT 기능은 크게 2가지로 구분 할 수 있습니다.

 1. Jwts 클래스

 2. Claims 인터페이스

 

Jwts클래스는 빌더패턴으로 구현이 되어 있습니다. 메소드를 체이닝 형식으로 붙이면 토큰값을 쉽게 만들 수 있습니다.

Claims 인터페이스는 Jwts클래스에서 사용하는 일종의 데이터 입니다. 

KEY - VALUE 형태로 값을 관리 할 수 있습니다.

 

이제 간단하게 토큰을 만드는 기능을 살펴 보겠습니다.

    
import java.util.Base64;
import java.util.Date;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
    
public class JwtTokenProvider 
    //암복호화에 사용되는 키 값 입니다.
    private static String secretKey = Base64.getEncoder().encodeToString("암호화키".getBytes());
    public String createToken() {
        Claims claims = Jwts.claims();  //나중에 서버에서 파싱해서 볼 데이터 입니다.
        claims.put("userId", "사용자이름");  //문자도 가능하고
        claims.put("roles", new Object() );  //객체도 가능합니다 ^^
        Date now = new Date();
        
        return Jwts.builder()
                .setHeaderParam(Header.TYPE, Header.JWT_TYPE) 
                .setClaims(claims) // 데이터를 넣어 줍니다
                .setIssuedAt(now)   // 토큰 발행 일자
                .setExpiration(new Date(now.getTime() + (1000L * 60 * 30))) // 만료 기간 입니다
                .signWith(SignatureAlgorithm.HS256, secretKey) // 암호화 알고리즘과 암복호화에 사용할 키를 넣어줍니다
                .compact(); // Token 생성
    }    
}

 

사용자가 로그인을 성공하면 위 createToken에 정보를 담아서 반환하여 주면 됩니다.

Claims 인터페이스에는 담아둘 정보를 넣으면 됩니다.

그리고나서 이제 필터 클래스나 인터셉터 클래스에서 해당 정보를 확인하면 됩니다.

 

이제 해당 값을 검증하는 메소드 입니다.

검증하는 메소드는 필터 클래스나 인터셉터 클래스에서 동작하면 될 것 입니다.

    
import java.util.Base64;
import java.util.Date;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
    
public class JwtTokenProvider 
    //암복호화에 사용되는 키 값 입니다.
    private static String secretKey = Base64.getEncoder().encodeToString("암호화키".getBytes());

    //생략...

    // Jwt Token의 유효성 및 만료 기간 검사합니다
    public boolean validateToken(String jwtToken) {
        try {
            Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken);
            return !claims.getBody().getExpiration().before(new Date());
        } catch (Exception e) {
            return false;
        }
    }
    
    // Jwt Token에서 데이터를 전달 합니다.
    public Claims getInformation(String token) {
        Claims claims =Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
        return claims;
    }

    
}

 

validateToken 메소드에 요청받은 jwt 토큰값을 확인 해 주어 만약 참인경우에는 getInformation 메소드를 동작시키면 됩니다.

Claims 인터페이스는 내부적으로 자바의 대표적인Collection인 Map을 상속받고 있습니다.

그러므로 원하는 데이터를 key, value로 넣어주면 서버에서 원하는 정보를 쉽게 확인 할 수 있겠습니다.

Map을 상속받고 있습니다.

 

이제 위 코드를 원하는 부분에 붙이기만 하면 됩니다.

실제 만료된 키 값과 만료되지 않는 키 값이 어떻게 나오는지 아래 사진을 보아주세요.

해더.내용.서명 형식의 데이터를 볼 수 있습니다.

 

JWT를 활용하는 방식은 위 내용처럼,

세션에 로그인 정보를 유지하는 방식에서 클라이언트 브라우저에게 정보를 갖게하는 방식으로 바뀐 내용 입니다.

결국 저거 하나만 가지고 로그인 기능을 구현했다고는 할 수 없겠네요. ^-^

 

* JwtTokenProvider 클래스 샘플(깃허브)

https://github.com/TaeSeungRyu/sample/tree/main/Java%20JWT%20%ED%86%A0%ED%81%B0

 

* JwtTokenProvider 클래스 샘플(다운로드)

JwtTokenProvider.java
0.00MB

 

이상으로 간단하게 살펴본 Spring에서의 JWT 방식이였습니다.

궁금한점 또는 틀린부분은 언제든 연락주세요! 👻

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글