日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

restfull加签_SpringBoot RestFull API签名

發布時間:2025/3/8 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 restfull加签_SpringBoot RestFull API签名 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、需求如下

對指定的API路徑進行簽名認證,對于沒有指定的無需認證,認證具體到方法。

二、查閱資料與開發

1.了解JWT,實際上用的開源jjwt

2.編寫自定義注解

3.編寫攔截器,主要是攔截特定的url進行簽名驗證,這里解析請求的handler是否有包含自定義注解

確定思路后,開始編寫代碼

A、寫工具,我在網上找的,代碼不復雜,一看就懂,代碼如下/**

* @Title: TokenUtils.java

* @Description:

* @Copyright: Copyright (c) 2018

* @Company:http://www.sinocon.cn

* @author Administrator

* @date 2018年8月21日

* @version 1.0

*/

package cn.sinocon.hive.utils;

import java.security.Key;

import java.util.Date;

import javax.crypto.spec.SecretKeySpec;

import javax.xml.bind.DatatypeConverter;

import cn.hutool.core.date.DateUtil;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.JwtBuilder;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

/**

* @Title: TokenUtils

* @Description:

* @author:Administrator

* @date 2018年8月21日

*/

public class TokenUtils {

/**

* 簽名秘鑰

*/

public static final String SECRET = "LHqDYnwpy7jzhmWdIy7EW3ER64mNlAGKRZWLKFvSKIyWWX";

/**

* 生成token

*

* @param id

* 一般傳入userName

* @return

*/

public static String createJwtToken(String id) {

String issuer = "www.zuidaima.com";

String subject = "8vfu3wqEidZve2";

long ttlMillis = System.currentTimeMillis();

return createJwtToken(id, issuer, subject, ttlMillis);

}

/**

* 生成Token

*

* @param id

* 編號

* @param issuer

* 該JWT的簽發者,是否使用是可選的

* @param subject

* 該JWT所面向的用戶,是否使用是可選的;

* @param ttlMillis

* 簽發時間

* @return token String

*/

public static String createJwtToken(String id, String issuer, String subject, long ttlMillis) {

// 簽名算法 ,將對token進行簽名

SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

// 生成簽發時間

long nowMillis = System.currentTimeMillis();

Date now = new Date(nowMillis);

// 通過秘鑰簽名JWT

byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);

Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

// Let's set the JWT Claims

JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject).setIssuer(issuer)

.signWith(signatureAlgorithm, signingKey);

// if it has been specified, let's add the expiration

if (ttlMillis >= 0) {

long expMillis = nowMillis + ttlMillis;

Date exp = new Date(expMillis);

builder.setExpiration(exp);

}

// Builds the JWT and serializes it to a compact, URL-safe string

return builder.compact();

}

// Sample method to validate and read the JWT

public static Claims parseJWT(String jwt) {

// This line will throw an exception if it is not a signed JWS (as

// expected)

Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(SECRET)).parseClaimsJws(jwt)

.getBody();

return claims;

}

public static void main(String[] args) {

System.out.println(TokenUtils.createJwtToken("page=10"));

}

}

B、編寫注解/**

* @Title: RequireSignature.java

* @Description:

* @Copyright: Copyright (c) 2018

* @Company:http://www.sinocon.cn

* @author Administrator

* @date 2018年8月18日

* @version 1.0

*/

package cn.sinocon.hive.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* @Title: RequireSignature

* @Description:

* @author:Administrator

* @date 2018年8月18日

*/

@Target({ElementType.METHOD})// 可用在方法名上

@Retention(RetentionPolicy.RUNTIME)// 運行時有效

public @interface RequireSignature {

}

C。編寫攔截器/**

* @Title: LoginInterceptor.java

* @Description:

* @Copyright: Copyright (c) 2018

* @Company:http://www.sinocon.cn

* @author Administrator

* @date 2018年8月18日

* @version 1.0

*/

package cn.sinocon.hive.interceptor;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import org.springframework.stereotype.Component;

import org.springframework.util.ObjectUtils;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.hutool.core.date.DateUtil;

import cn.hutool.core.util.ObjectUtil;

import cn.sinocon.hive.annotation.RequireSignature;

import cn.sinocon.hive.utils.TokenUtils;

import io.jsonwebtoken.Claims;

/**

* @Title: LoginInterceptor

* @Description:

* @author:Administrator

* @date 2018年8月18日

*/

@Component

public class LoginInterceptor extends HandlerInterceptorAdapter {

public final static String ACCESS_TOKEN = "accessToken";

public final static String EXCEPTION_MSG = "signature does not match locally computed signature,error code:";

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

if (!(handler instanceof HandlerMethod)) {

return true;

}

HandlerMethod handlerMethod = (HandlerMethod) handler;

Method method = handlerMethod.getMethod();

RequireSignature methodAnnotation = method.getAnnotation(RequireSignature.class);

// 有 @RequireSignature 注解,需要認證

if (ObjectUtil.isNotNull(methodAnnotation)) {

// 判斷是否存在令牌信息,如果存在,則允許登錄

String accessToken = request.getParameter(ACCESS_TOKEN);

if (StringUtils.isBlank(accessToken)) {

// 需要認證才行

throw new RuntimeException(EXCEPTION_MSG + "400003");

}

Claims claims = null;

try {

claims = TokenUtils.parseJWT(accessToken);

} catch (Exception e) {

throw new RuntimeException(EXCEPTION_MSG + "400005");

}

// 簽名格式錯誤,請按照約定生成簽名

String[] firstParam = claims.getId().split("=");

if (ObjectUtils.isEmpty(firstParam)) {

throw new RuntimeException(EXCEPTION_MSG + "400005");

}

// 簽名被篡改

String parameter = request.getParameter(firstParam[0]);

if (!firstParam[1].equals(parameter)) {

throw new RuntimeException(EXCEPTION_MSG + "400006");

}

boolean validation = false;

// 獲取簽名生成的時間,簽名有效10分鐘

try {

long timeInMillis = DateUtil.calendar(Long.parseLong(claims.get("exp") + "")).getTimeInMillis();

validation = DateUtil.calendar(System.currentTimeMillis())

.getTimeInMillis() < (timeInMillis + 10 * 60 * 1000);

} catch (Exception e) {

throw new RuntimeException(EXCEPTION_MSG + "400005");

}

// 超時

if (validation) {

throw new RuntimeException(EXCEPTION_MSG + "400007");

}

}

return super.preHandle(request, response, handler);

}

}

D。配置攔截器/**

* @Title: ResourceConfig.java

* @Description:

* @Copyright: Copyright (c) 2018

* @Company:http://www.sinocon.cn

* @author Administrator

* @date 2018年8月6日

* @version 1.0

*/

package cn.sinocon.hive.config;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import cn.sinocon.hive.interceptor.LoginInterceptor;

/**

* @Title: ResourceConfig

* @Description:

* @author:Administrator

* @date 2018年8月6日

*/

@Configuration

public class ResourceConfig implements WebMvcConfigurer {

/*

* 默認首頁的設置,當輸入域名是可以自動跳轉到默認指定的網頁

*

*

Title: addViewControllers

*

*

Description:

*

* @param registry

*

* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#

* addViewControllers(org.springframework.web.servlet.config.annotation.

* ViewControllerRegistry)

*

*/

@Override

public void addViewControllers(ViewControllerRegistry registry) {

registry.addViewController("/").setViewName("forward:/index.html");

}

/* (non-Javadoc)

*

Title: addInterceptors

*

Description: 攔截器配置

* @param registry

* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#addInterceptors(org.springframework.web.servlet.config.annotation.InterceptorRegistry)

*/

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/api/**");

WebMvcConfigurer.super.addInterceptors(registry);

}

}

E、在調用的controller方法中加上注解@RequireSignature

大功告成

總結

以上是生活随笔為你收集整理的restfull加签_SpringBoot RestFull API签名的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。