본문 바로가기

카테고리 없음

채용사이트만들기 5일차- JWT 토큰만료시 대응

728x90

 

SecurityService.java

public interface SecurityService {

	String createToken(String subject,long ttlMillis);
	String getSubject(String token);
	Boolean jwtExpireCheck(int time);
	
}

service단에서 토큰시간과 현재시간을 비교하여 토큰이 아직 유효한지를 체크하였다.

package com.devtest.devtest.service;


import java.security.Key;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.springframework.stereotype.Service;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Service
public class SecurityServiceImpl implements SecurityService {


    private static String secretKey = "시크릿키";

    @Override
    public String createToken(String subject, long ttlMillis) {
        // TODO Auto-generated method stub
//		System.out.println(subject);
        if (ttlMillis == 0) {
            throw new RuntimeException("토큰 만료기간은 0이상 이어야합니다.");
        }

        //HS256
        System.out.println("HS256 서명알고리즘으로 토큰 생성중");
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySeBytes = DatatypeConverter.parseBase64Binary(secretKey);
        Key signingKey = new SecretKeySpec(apiKeySeBytes, signatureAlgorithm.getJcaName());

        JwtBuilder builder = Jwts.builder()
                .setSubject(subject)
                .signWith(signatureAlgorithm, signingKey);

        long nowMillis = System.currentTimeMillis();
        builder.setExpiration(new Date(nowMillis + ttlMillis));
        return builder.compact();
    }

    //token

    @Override
    public String getSubject(String token) {
        // TODO Auto-generated method stub

        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
                .parseClaimsJws(token).getBody();

        return claims.getSubject();
    }

    @Override
    public Boolean jwtExpireCheck(int time) {
        int CurrentTime = (int) ((new Date().getTime()));

        if (time >= CurrentTime) {
            System.out.println("유효시간 남음");
            return true;
        } else {
            System.out.println("유효시간 끝남");
            return false;
        }


    }
}

다음과 같이 nologin시, 토큰만료시,토큰이 유효할시 3가지로 나누어서 return 시켜주었다.

@RequestMapping(value = "/home", method = RequestMethod.GET)
    @CrossOrigin(origins = "http://localhost:3000")
    public String getAuthInfo(HttpServletRequest req) throws ExpiredJwtException {
        Boolean expireCheck = null;
        String authorization = req.getHeader("Authorization");
        System.out.println("authorization : " + authorization);

        if(authorization.equals("null")) {
            System.out.println("noLogin");
            return "noLogin";
        }else {
            try{
                String payload = securityService.getSubject(authorization);

                JSONObject json = new JSONObject(payload.replaceAll("=", ":"));

//        System.out.println(json);

                int exp = json.getInt("exp");
//        System.out.println(exp);

                expireCheck = securityService.jwtExpireCheck(exp);

                return expireCheck.toString();
            }catch (JwtException e){
                expireCheck = false;
                e.printStackTrace();
            }
        }

        return expireCheck.toString();


    }

리액트 단에서 해당토큰을 확인하여 유효할시 session을 clear시키고 다시 로그인하게 만들었다.

.then((res) => {
            console.log(res.data);

            if (res.data == true){
                alert("환영합니다!")
            }else if(res.data == false){
                alert("로그인 유효시간 종료!")
                sessionStorage.clear()
                window.location.href = "/";

            }else if(res.data == "noLogin"){console.log("noLogin");}
          }

 

728x90