spring boot+jwt api 구현 token 인증 상세 설명

14532 단어 jwtapitoken 인증
머리말
이 편 은 jwt(json web token)의 사용 을 공유 합 니 다.그녀 는 주로 인터페이스 에 접근 하 는 token 과 검증 을 생 성 하 는 데 사 용 됩 니 다.springboot 와 단독으로 결합 하여 api 인터페이스 token 검증 을 개발 하 는 것 이 편리 합 니 다.jwt 의 token 에 사용자 의 정보 가 저장 되 어 있 고 암호 화 되 어 있 기 때문에 분포 식 에 적 용 됩 니 다.이렇게 직접 합 시다.정 보 는 사용자 로 컬 에 저장 되 어 서버 에서 sessiion 이나 token 의 압력 을 줄 였 습 니 다.
다음 빠 른 사용:

<!--jwt-->
<dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt</artifactId>
 <version>0.9.0</version>
</dependency>
<!--   FastJson  -->
<dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>fastjson</artifactId>
 <version>1.2.44</version>
</dependency>
일반적으로 jwt 를 사용 하여 3 가지 결과 에 도달 합 니 다.
  • token 생 성
  • token 이 효과 가 있 는 지 검증
  • token 에서 jwt 정보(주요 사용자 정보)얻 기
  • 토 큰 생 성
    jjwt 의존 도 를 도입 한 후 token 을 생 성 하 는 것 이 편리 합 니 다.하나의 token 에 있어 유일한 것 이 고 거 스 를 수 없 는 것 을 대표 하기 때문에 우 리 는 생 성 할 때 유일한 데 이 터 를 추가 해 야 합 니 다.예 를 들 어 아래 의 id:
    
    long currentTime = System.currentTimeMillis();
    return Jwts.builder()
      .setId(UUID.randomUUID().toString())
      .setIssuedAt(new Date(currentTime)) //    
      .setSubject("system") //  
      .setIssuer("shenniu003") //     
      .setAudience("custom") //    
      .compressWith(CompressionCodecs.GZIP) //      
    
      .signWith(SignatureAlgorithm.HS256, encryKey) //    
      .setExpiration(new Date(currentTime + secondTimeOut * 1000)) //     
      .addClaims(claimMaps) //cla  
      .compact();
    uid 를 통 해 유일한 id 정 보 를 표시 합 니 다.물론 token 을 암호 화 할 때 비밀 키 를 사용 해 야 합 니 다.jwt 는 HS 256,HS 265,Md5 등 복잡 하고 자주 사용 하 는 암호 화 방식 을 지원 합 니 다.
    jwt 가 생 성 한 token 의 내용 은 세 부분 으로 나 뉜 다.head 정보,payload 정보,sign 정보 이다.보통 우리 가 해 야 할 일 은 payload 에 사용자 정 보 를 추가 하 는 것 이다(예 를 들 어 계 정,닉네임,권한 등 이지 만 비밀 번 호 는 포함 되 지 않 는 다).jwt 의 token 에 대해 어느 정도 알 고 있 는 후에 실제 생 성 된 token 값 을 살 펴 보 겠 습 니 다.
    
    eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAAFWMTQ7CIBSE7_LWkPDzaEsP4QnYINCIptX4INE0vbtg4sLlfPPN7HAtGWbwg1BKL4GrcbEcIwpujZF8iiEpjXFapAAG2ReYpUEcR2VxYED13Nb0ppLW3hP1eEnblqsQuiFfY0OhUrl3I70evweU_aFSejZhd7DlcDv5NTmYHUilHTD3rf_hAccHRTv--7YAAAA.i4xwoQtaWI0-dwHWN8uZ4DBm-vfli5bavYU9lRYxU5E
    token 이 유효한 지 검증
    token 이 생 성 될 때 수반 되 는 실효 시간 이 있 습 니 다.이 경우 setExpiration 함수 로 만 료 시간 을 설정 할 수 있 습 니 다.jwt 의 유효 시간 은 미 끄 러 지 는 것 이 아니 라 는 것 을 기억 하 십시오.즉,어떠한 처리 도 하지 않 을 때 첫 번 째 설정 의 실효 시간 에 도 착 했 을 때 거의 사용 되 지 않 습 니 다.token 이 만 료 되 었 는 지 여 부 를 가 져 오 려 면 다음 과 같은 방식 을 사용 할 수 있 습 니 다.
    
    public static boolean isExpiration(String token, String encryKey) {
     try {
      return getClaimsBody(token, encryKey)
        .getExpiration()
        .before(new Date());
     } catch (ExpiredJwtException ex) {
      return true;
     }
    }
    여기에 date before 를 사용 하여 얻 은 만 료 시간 과 현재 시간 을 비교 하여 계속 유효한 지 여 부 를 판단 합 니 다.주의해 야 할 것 은 token 이 실 효 된 후에 getClaims Body(token,encry Key)를 통 해 정 보 를 얻 으 면 Expired JwtException 오 류 를 보고 하고 만 료 되 었 다 고 생각 할 수 있 습 니 다.
    token 의 jwt 정보 가 져 오기(주요 사용자 정보)
    일반적으로 저 희 는 로그 인 사용자 정 보 를 jwt 에서 생 성 된 token 에 저장 해 야 합 니 다.여 기 는 addClaims(claimMaps)를 통 해 map 를 전달 하여 정 보 를 설정 할 수 있 고 반대로 token 의 사용자 정 보 를 얻 으 려 면 이렇게 해 야 합 니 다.
    
     return Jwts.parser()
       .setSigningKey(encryKey)
       .parseClaimsJws(token)
       .getBody();
    이때 body 는 Claims 형식 을 가 져 옵 니 다.사용자 정 보 를 가 져 와 야 합 니 다.주의해 야 할 것 은 addClaims 가 정 보 를 저장 할 때 저 장 된 map 값 이 만들어 지지 않 으 면 완전한 실체 대상 이 저장 되면 LinkHasMap 형식 으로 매 핑 됩 니 다.다음 과 같 습 니 다.

    따라서 보통 저장 할 때 json 화 됩 니 다.다음 과 같은 코드 입 니 다.
    
     claimMaps.forEach((key, val) -> {
      claimMaps.put(key, JSON.toJSONString(val));
     });
    그리고 get 방법 을 통 해 우리 가 저장 한 정 보 를 얻 고 json 의 반 직렬 화 입 니 다.
    
    /**
    *   body   
    *
    * @param token
    * @param encryKey
    * @param key
    * @return
    */
    public static Object getVal(String token, String encryKey, String key) {
     return getJws(token, encryKey).getBody().get(key);
    }
    
    /**
     *   body   ,json     
     *
     * @param token
     * @param encryKey
     * @param key
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T getValByT(String token, String encryKey, String key, Class<T> tClass) {
     try {
      String strJson = getVal(token, encryKey, key).toString();
      return JSON.parseObject(strJson, tClass);
     } catch (Exception ex) {
      return null;
     }
    }
    여기에 오 면 Jwt 의 Util 코드 가 기본적으로 완성 되 었 습 니 다.다음은 완전한 코드 예 를 보 여 드 리 겠 습 니 다.참고 하 시기 바 랍 니 다.
    
    public class JwtUtil {
    
     /**
      *   token - json  map  
      *
      * @param claimMaps
      * @param encryKey
      * @param secondTimeOut
      * @return
      */
     public static String getTokenByJson(Map<String, Object> claimMaps, String encryKey, int secondTimeOut) {
      return getToken(claimMaps, true, encryKey, secondTimeOut);
     }
    
     /**
      *   token
      *
      * @param claimMaps
      * @param isJsonMpas
      * @param encryKey
      * @param secondTimeOut
      * @return
      */
     public static String getToken(Map<String, Object> claimMaps, boolean isJsonMpas, String encryKey, int secondTimeOut) {
    
      if (isJsonMpas) {
       claimMaps.forEach((key, val) -> {
        claimMaps.put(key, JSON.toJSONString(val));
       });
      }
      long currentTime = System.currentTimeMillis();
      return Jwts.builder()
        .setId(UUID.randomUUID().toString())
        .setIssuedAt(new Date(currentTime)) //    
        .setSubject("system") //  
        .setIssuer("shenniu003") //     
        .setAudience("custom") //    
        .compressWith(CompressionCodecs.GZIP) //      
    
        .signWith(SignatureAlgorithm.HS256, encryKey) //    
        .setExpiration(new Date(currentTime + secondTimeOut * 1000)) //     
        .addClaims(claimMaps) //cla  
        .compact();
     }
    
     /**
      *   token  claims  
      *
      * @param token
      * @param encryKey
      * @return
      */
     private static Jws<Claims> getJws(String token, String encryKey) {
      return Jwts.parser()
        .setSigningKey(encryKey)
        .parseClaimsJws(token);
     }
    
     public static String getSignature(String token, String encryKey) {
      try {
       return getJws(token, encryKey).getSignature();
      } catch (Exception ex) {
       return "";
      }
     }
    
     /**
      *   token head  
      *
      * @param token
      * @param encryKey
      * @return
      */
     public static JwsHeader getHeader(String token, String encryKey) {
      try {
       return getJws(token, encryKey).getHeader();
      } catch (Exception ex) {
       return null;
      }
     }
    
     /**
      *   payload body  
      *
      * @param token
      * @param encryKey
      * @return
      */
     public static Claims getClaimsBody(String token, String encryKey) {
      return getJws(token, encryKey).getBody();
     }
    
     /**
      *   body   
      *
      * @param token
      * @param encryKey
      * @param key
      * @return
      */
     public static Object getVal(String token, String encryKey, String key) {
      return getJws(token, encryKey).getBody().get(key);
     }
    
     /**
      *   body   ,json     
      *
      * @param token
      * @param encryKey
      * @param key
      * @param tClass
      * @param <T>
      * @return
      */
     public static <T> T getValByT(String token, String encryKey, String key, Class<T> tClass) {
      try {
       String strJson = getVal(token, encryKey, key).toString();
       return JSON.parseObject(strJson, tClass);
      } catch (Exception ex) {
       return null;
      }
     }
    
     /**
      *     
      *
      * @param token
      * @param encryKey
      * @return
      */
     public static boolean isExpiration(String token, String encryKey) {
      try {
       return getClaimsBody(token, encryKey)
         .getExpiration()
         .before(new Date());
      } catch (ExpiredJwtException ex) {
       return true;
      }
     }
    
     public static String getSubject(String token, String encryKey) {
      try {
       return getClaimsBody(token, encryKey).getSubject();
      } catch (Exception ex) {
       return "";
      }
     }
    }
    필터 인증 token
    기본 적 인 JwtUtil 도구 가 있 습 니 다.springboot 프로젝트 에 사용 해 야 합 니 다.일반적으로 로그 인 권한 수여 token 인증 은 필 터 를 통 해 작 동 할 수 있 습 니 다.authenFilter 를 만 들 고 post 가 요청 한 token 을 검증 할 수 있 습 니 다.
    
    public class AuthenFilter implements Filter {
     @Override
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
      HttpServletRequest rq = (HttpServletRequest) servletRequest;
      HttpServletResponse rp = (HttpServletResponse) servletResponse;
      RpBase rpBase = new RpBase();
      try {
       //   post
       if (!rq.getMethod().equalsIgnoreCase("post")) {
        filterChain.doFilter(servletRequest, servletResponse);
        return;
       }
    
       String token = rq.getHeader("token");
       if (StringUtils.isEmpty(token)) {
        rpBase.setMsg(" token");
        return;
       }
    
       //jwt  
       MoUser moUser = JwtUtil.getValByT(token, WebConfig.Token_EncryKey, WebConfig.Login_User, MoUser.class);
       if (moUser == null) {
        rpBase.setMsg("token   ");
        return;
       }
    
       System.out.println("token  :" + moUser.getNickName());
    
       filterChain.doFilter(servletRequest, servletResponse);
      } catch (Exception ex) {
      } finally {
       if (!StringUtils.isEmpty(rpBase.getMsg())) {
        rp.setCharacterEncoding("utf-8");
        rpBase.setCode(HttpStatus.BAD_REQUEST.value());
        rp.getWriter().write(JSON.toJSONString(rpBase));
       }
      }
     }
    }
    사용자 정의 필터 AuthenFilter 가 유효 하 다 면 용기 에 등록 해 야 합 니 다.여 기 는 인 코딩 방식 을 통 해@WebFilter 주 해 를 통 해 용기 에 추가 할 수 있 습 니 다.
    
    @Configuration
    public class WebFilterConfig {
    
     @Bean
     public FilterRegistrationBean setFilter() {
    
      FilterRegistrationBean registrationBean = new FilterRegistrationBean();
      registrationBean.setFilter(new AuthenFilter());
      registrationBean.addUrlPatterns("/api/*");
      registrationBean.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
    
      return registrationBean;
     }
    }
    addUrl Patterns 가 필터 역할 을 하 는 url 연결 과 일치 하 는 것 을 주의 하 십시오.수요 에 따라 정 합 니 다.효 과 를 검증 하기 위해 서 저 는 두 개의 인터페이스 getToken 과 t0 을 만 들 었 습 니 다.각각 token 과 post 조회 인 터 페 이 스 를 가 져 왔 습 니 다.코드 는 다음 과 같 습 니 다.
    
    @RestController
    public class TestController {
    
     @PostMapping("/api/t0")
     public String t0() throws MyException {
    
      return UUID.randomUUID().toString();
     }
    
     @GetMapping("/token/{userName}")
     public String getToken(@PathVariable String userName) {
    
      MoUser moUser = new MoUser();
      moUser.setUserName(userName);
      moUser.setNickName(userName);
    
      Map<String, Object> map = new HashMap<>();
      map.put(WebConfig.Login_User, moUser);
    
      return JwtUtil.getTokenByJson(map,
        WebConfig.Token_EncryKey,
        WebConfig.Token_SecondTimeOut);
     }
    }
    최종 적 으로 헤드 를 통 해 token 값 을 전달 하여 t01 인 터 페 이 스 를 방문 하여 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.

    token 은 유효 시간 후 접근 에 실 패 했 습 니 다.token 을 새로 가 져 오고 t01 인 터 페 이 스 를 방문 하여 성공 적 인 정 보 를 얻 었 습 니 다.

    git 주소:https://github.com/shenniubuxing3
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기