日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Vue+Springboot實(shí)現(xiàn)接口簽名的示例代碼

瀏覽:25日期:2022-09-30 14:36:12
1、實(shí)現(xiàn)思路

接口簽名目的是為了,確保請(qǐng)求參數(shù)不會(huì)被篡改,請(qǐng)求的數(shù)據(jù)是否已超時(shí),數(shù)據(jù)是否重復(fù)提交等。

Vue+Springboot實(shí)現(xiàn)接口簽名的示例代碼

接口簽名示意圖

客戶端提交請(qǐng)求時(shí),將以下參數(shù)按照約定簽名方式進(jìn)行簽名,隨后將參數(shù)和簽名一同提交服務(wù)端:

1.請(qǐng)求頭部分(header)appid:針對(duì)不同的調(diào)用方分配不同的appid。noce:請(qǐng)求的流水號(hào),防止重復(fù)提交。timestamp:請(qǐng)求時(shí)間戳,驗(yàn)證請(qǐng)求是否已超時(shí)失效。

2.數(shù)據(jù)部分Path:按照path中的參數(shù)將所有key=value進(jìn)行拼接。Query:按照所有key=value進(jìn)行拼接。Form:按照所有key=value進(jìn)行拼接Body:Json,按照所有key=value進(jìn)行拼接。String,整個(gè)字符串作為一個(gè)拼接。

Vue+Springboot實(shí)現(xiàn)接口簽名的示例代碼

簽名

服務(wù)端提接收交請(qǐng)求后,同樣通過(guò)接收的“請(qǐng)求頭部分”、“數(shù)據(jù)部分”的參數(shù)進(jìn)行拼接。隨后驗(yàn)證客戶端提交的簽名是否正確。

2、代碼實(shí)現(xiàn)

客戶端(Vue)首先需要安裝“jsrsasign”庫(kù),以便實(shí)現(xiàn) RSA 加密、解密、簽名、驗(yàn)簽等功能。官方地址:http://kjur.github.io/jsrsasign/執(zhí)行以下命令:

npm install jsrsasign -save

安裝完成后,封裝sign.js

import {KJUR, KEYUTIL, hex2b64, b64tohex} from ’jsrsasign’// 簽名算法const ALGORITHM = ’SHA256withRSA’// 私鑰簽名const RSA_SIGN = (privateKey, src) => { const signature = new KJUR.crypto.Signature({’alg’: ALGORITHM}) // 來(lái)解析密鑰 const priKey = KEYUTIL.getKey(privateKey) signature.init(priKey) // 傳入待簽明文 signature.updateString(src) const a = signature.sign() // 轉(zhuǎn)換成base64,返回 return hex2b64(a) }// 公鑰驗(yàn)簽const RSA_VERIFY_SIGN = (publicKey, src, data) => { const signature = new KJUR.crypto.Signature({’alg’: ALGORITHM, ’prvkeypem’: publicKey}) signature.updateString(src) return signature.verify(b64tohex(data))}export { RSA_SIGN, RSA_VERIFY_SIGN}

客戶端(Vue)通過(guò)sign.js進(jìn)行加簽、驗(yàn)簽。

const src = ’我是一段測(cè)試字符串2’const publicKey = ’-----BEGIN PUBLIC KEY-----n’ + ’MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC35wxzdTzseajkYL06hEKBCEJun’ + ’JQ/nySId2oTnsxbLiSTEjpAESSbML1lqkKaIwjrSFZzyLMH6DirsoEQcATqqoCDUn’ + ’/H9QNVb5jMSAxxdQusQkTWz6k07bEuy1ppVjpGxNi8o2OGNd+lwPC/hOSDR7lpfmn’ + ’aXLIjEwKSXzil7YAHQIDAQABn’ + ’-----END PUBLIC KEY-----’const privateKey = ’-----BEGIN PRIVATE KEY-----n’ + ’MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALfnDHN1POx5qORgn’ + ’vTqEQoEIQm4lD+fJIh3ahOezFsuJJMSOkARJJswvWWqQpojCOtIVnPIswfoOKuygn’ + ’RBwBOqqgINT8f1A1VvmMxIDHF1C6xCRNbPqTTtsS7LWmlWOkbE2LyjY4Y136XA8Ln’ + ’+E5INHuWl+ZpcsiMTApJfOKXtgAdAgMBAAECgYB2PAcGSC7mPoW2ZvfiIlx7hurmn’ + ’0885D1hu5yohqUOTklXgRWQUTU+zYRHU8LERJgcZQKoKDXqdIPS584Q2mRe0uZMrn’ + ’vaiaBVEnHQreUJUQ8UN12pPUdBHDZvOk3L7/fZHk6A8uy5e09p2rsn+Vfki3zijpn’ + ’7Pd758HMtjuiHBb2QQJBAOuN6jdWBr/zb7KwM9N/cD1jJd6snOTNsLazH/Z3Yt0Tn’ + ’jlsFmRJ6rIt/+jaLKG6YTR8SFyW5LIQTbreeQHPw4FECQQDH3Wpd/mBMMcgpxLZ0n’ + ’F5p1ieza+VA5fbxkQ0hdubEP26B6YwhkTB/xMSOwEjmUI57kfgOTvub36/peb8rIn’ + ’JdwNAkB3fzwlrGeqMzYkIU15avomuki46TqCvHJ8jOyXHUOzQbuDI5jfDgrAjkECn’ + ’MKBnUq41J/lEMueJbU5KqmaqKrWxAkAyexlHnl1iQVymOBpBXkjUET8y26/IpZp0n’ + ’1I2tpp4zPCzfXK4c7yFOQTQbX68NXKXgXne21Ivv6Ll3KtNUFEPtAkBcx5iWU430n’ + ’0/s6218/enaa8jgdqw8Iyirnt07uKabQXqNnvbPYCgpeswEcSvQqMVZVKOaMrjKOn’ + ’G319Es83iq/mn’ + ’-----END PRIVATE KEY-----n’console.log(’明文:’, src)const data = RSA_SIGN(privateKey, src)console.log(’簽名后的結(jié)果:’, data)const res = RSA_VERIFY_SIGN(publicKey, src, data)console.log(’驗(yàn)簽結(jié)果:’, res)

服務(wù)端(Spring boot)接收請(qǐng)求后,需要對(duì)數(shù)據(jù)和簽名,進(jìn)行驗(yàn)證。

首先引入依賴——hutool工具包,Hutool是一個(gè)Java工具包,也只是一個(gè)工具包,它幫助我們簡(jiǎn)化每一行代碼,減少每一個(gè)方法,讓Java語(yǔ)言也可以“甜甜的”。

官網(wǎng)地址:https://www.hutool.cn/

在pom.xml下增加如下配置:

<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.3.5</version></dependency>

服務(wù)端(Spring boot)首先要獲取客戶端(Vue)請(qǐng)求的數(shù)據(jù),上文已經(jīng)描述了請(qǐng)求的數(shù)據(jù)有兩部分,分別是“請(qǐng)求頭部分”、“數(shù)據(jù)部分”。所以需要配置攔截器,對(duì)以上兩部分進(jìn)行獲取。

配置攔截器(MyInterceptor.java),代碼如下:

import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import org.springframework.util.StreamUtils;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Slf4j@Componentpublic class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//獲取請(qǐng)求參數(shù)String queryString = request.getQueryString();log.info('請(qǐng)求參數(shù):{}', queryString);// 獲取headerlog.info('key:{}',request.getHeader('timestamp'));MyHttpServletRequestWrapper myRequestWrapper = new MyHttpServletRequestWrapper(request);//獲取請(qǐng)求bodybyte[] bodyBytes = StreamUtils.copyToByteArray(myRequestWrapper.getInputStream());String body = new String(bodyBytes, request.getCharacterEncoding());log.info('請(qǐng)求體:{}', body);return true; }}

在獲取“請(qǐng)求體body”時(shí),由于“HttpServletRequest”只能讀取一次,攔截器讀取后,后續(xù)Controller在讀取時(shí)為空,所以需要重寫HttpServletRequestWrapper:

import org.springframework.util.StreamUtils;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * 緩存下來(lái)的HTTP body */ private byte[] body; public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);body = StreamUtils.copyToByteArray(request.getInputStream()); } @Override public ServletInputStream getInputStream() throws IOException {InputStream bodyStream = new ByteArrayInputStream(body);return new ServletInputStream(){ @Override public int read() throws IOException {return bodyStream.read(); } @Override public boolean isFinished() {return false; } @Override public boolean isReady() {return true; } @Override public void setReadListener(ReadListener readListener) { }}; } @Override public BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream())); }}

之后,需要?jiǎng)?chuàng)建過(guò)濾器,將“MyHttpServletRequestWrapper” 替換“ServletRequest”,代碼如下:

import lombok.extern.slf4j.Slf4j;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;@Slf4jpublic class RepeatedlyReadFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {ServletRequest requestWrapper = null;if(servletRequest instanceof HttpServletRequest) { requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) servletRequest);}if(requestWrapper == null) { filterChain.doFilter(servletRequest, servletResponse);} else { filterChain.doFilter(requestWrapper, servletResponse);} } @Override public void destroy() { }}

之后創(chuàng)建自定義配置,CorsConfig.java,將過(guò)濾器、攔截器加入配置:

import com.xyf.interceptor.MyInterceptor;import com.xyf.interceptor.RepeatedlyReadFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configurationpublic class CorsConfig extends WebMvcConfigurationSupport { private MyInterceptor myInterceptor; @Autowired public CorsConfig (MyInterceptor myInterceptor){this.myInterceptor = myInterceptor; } // 注冊(cè)過(guò)濾器 @Bean public FilterRegistrationBean<RepeatedlyReadFilter> repeatedlyReadFilter() {FilterRegistrationBean registration = new FilterRegistrationBean();RepeatedlyReadFilter repeatedlyReadFilter = new RepeatedlyReadFilter();registration.setFilter(repeatedlyReadFilter);registration.addUrlPatterns('/*');return registration; } @Override protected void addInterceptors(InterceptorRegistry registry) {// addPathPatterns添加需要攔截的命名空間;// excludePathPatterns添加排除攔截命名空間registry.addInterceptor(myInterceptor).addPathPatterns('/**');//.excludePathPatterns('/api/sys/login') }}

最后,完成驗(yàn)簽,代碼如下:

import cn.hutool.core.codec.Base64;import cn.hutool.crypto.SecureUtil;import cn.hutool.crypto.asymmetric.Sign;import cn.hutool.crypto.asymmetric.SignAlgorithm;byte[] data = '我是一段測(cè)試字符串2'.getBytes();String publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC35wxzdTzseajkYL06hEKBCEJun' +'JQ/nySId2oTnsxbLiSTEjpAESSbML1lqkKaIwjrSFZzyLMH6DirsoEQcATqqoCDUn' +'/H9QNVb5jMSAxxdQusQkTWz6k07bEuy1ppVjpGxNi8o2OGNd+lwPC/hOSDR7lpfmn' +'aXLIjEwKSXzil7YAHQIDAQAB';Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA,null,publicKey);//客戶端傳來(lái)的簽名String qm = 'IhY3LNuFn0isud1Pk6BL2eJV3Jl/UzDCYsdG9CYyJwOGqwnzStsv/RiYLnVP4bnQh1NRPMazY6ux/5Zz5Ypcx6RI5W1p5BDbO2afuIZX7x/eIu5utwsanhbxEfvm3XOsyuTbnMDh6BQUrXb4gUz9qgt9IXWjQdqnQRRv3ywzWcA=';byte[] signed = Base64.decode(qm);//驗(yàn)證簽名boolean verify = sign.verify(data, signed);3、公鑰、私鑰生成

可通過(guò)一些網(wǎng)站在線生成公鑰、私鑰網(wǎng)址:https://www.bejson.com/enc/rsa/

Vue+Springboot實(shí)現(xiàn)接口簽名的示例代碼

bejson在線生成公鑰、私鑰

4、其他問(wèn)題

由于客戶端加簽、服務(wù)端驗(yàn)簽。所以加簽、驗(yàn)簽的方式務(wù)必一致,否則將無(wú)法驗(yàn)證簽名。Vue、Java有不同的簽名工具庫(kù),使用前要做好測(cè)試。

到此這篇關(guān)于Vue+Springboot實(shí)現(xiàn)接口簽名的示例代碼的文章就介紹到這了,更多相關(guān)Springboot 接口簽名內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久久久97| 日韩视频一区二区三区在线播放免费观看| 91精品一区国产高清在线gif | 美女视频黄久久| 日韩高清在线一区| 青草久久视频| 久久福利在线| 精品国产一区二| 日本激情一区| 日韩精品一区二区三区免费观看| 麻豆理论在线观看| 丝袜美腿诱惑一区二区三区| 成人片免费看| 亚洲一级网站| 不卡中文字幕| 久久激情中文| 亚洲欧洲一区| 日韩在线麻豆| 欧美91在线| 蜜桃精品在线| 麻豆精品91| 国产精品任我爽爆在线播放| 美女精品视频在线| 天堂√8在线中文| 伊人成人网在线看| 亚洲精品自拍| 国产精品18| 日韩不卡免费高清视频| 亚洲综合三区| 国产精品亚洲二区| 麻豆一区在线| 欧美丝袜一区| 亚洲精品在线a| 九九九精品视频| 久久人人97超碰国产公开结果| 亚洲尤物在线| 久久精品凹凸全集| 国产日韩电影| 亚洲欧美视频| 国产精品日韩精品在线播放| 中文字幕在线看片| 天使萌一区二区三区免费观看| 日本视频一区二区| av综合电影网站| 亚洲欧洲美洲国产香蕉| 国产日韩免费| 日产精品一区| 日韩精品视频在线看| 国产传媒在线观看| 天堂va蜜桃一区二区三区| 国产精品日本一区二区不卡视频| 久久网站免费观看| 国产精品手机在线播放| 欧美福利专区| 久久国产麻豆精品| 黄色网一区二区| 亚洲欧美网站| 国产欧洲在线| 老牛国产精品一区的观看方式| 久久福利精品| 蜜臀a∨国产成人精品| 国产欧美一区二区三区米奇| 日韩精品免费一区二区三区| 日韩国产在线观看| 精精国产xxxx视频在线野外| 日韩一区精品| 久久久久久久久丰满| 91精品一区| 午夜欧美理论片| 国产精品白丝一区二区三区| 国产综合婷婷| 精品视频国内| 亚洲毛片在线免费| 国产一区清纯| 精品国产91| 水野朝阳av一区二区三区| 97精品国产一区二区三区| 日韩精品91亚洲二区在线观看| 国产高清不卡| 国产欧美另类| 石原莉奈在线亚洲二区| 中文在线а√天堂| 国产精品亚洲欧美一级在线 | 国产aa精品| 少妇精品久久久一区二区三区| 涩涩av在线| 久久亚洲精精品中文字幕| 四虎在线精品| 欧美日韩少妇| 丝袜美腿诱惑一区二区三区| 免费在线播放第一区高清av| 日韩中文字幕| 丝袜美腿成人在线| 欧美日韩三区| 激情欧美国产欧美| 亚洲永久av| 精品三区视频| 国产精品久久久久毛片大屁完整版| 蜜乳av另类精品一区二区| 秋霞国产精品| 中文字幕在线看片| 日韩av专区| 久久一区亚洲| 久久不见久久见免费视频7| 三级欧美在线一区| 中文精品视频| 91九色精品| 国产99亚洲| 欧美日韩中文一区二区| 久久青草久久| 亚洲成av人片一区二区密柚 | 免费观看亚洲天堂| 国产精品中文| 久久国产精品色av免费看| 日韩和欧美的一区| 日本aⅴ免费视频一区二区三区| 亚洲精品第一| 丝袜美腿一区二区三区| 野花国产精品入口| 好吊日精品视频| 国产精品日韩久久久| 欧美在线影院| 亚洲综合不卡| 中文字幕日本一区| 日韩欧美美女在线观看| 久久亚洲电影| 亚洲影院天堂中文av色| 人人爽香蕉精品| 亚洲天堂免费| 日本免费新一区视频| 日韩av影院| 国产亚洲观看| 国产欧美二区| 九九99久久精品在免费线bt| 日韩不卡一区| 国产字幕视频一区二区| 国产精品美女久久久| 一区二区三区国产在线| 亚洲18在线| 日本麻豆一区二区三区视频| 国产精品手机在线播放| 韩国女主播一区二区三区| 日韩一区二区在线免费| 欧美特黄一级大片| 久久av在线| 日韩精品1区2区3区| 国产精品17p| 日韩国产在线| 99riav1国产精品视频| 中文字幕亚洲精品乱码| 国产精品流白浆在线观看| 久久久久久久欧美精品| 香蕉久久久久久久av网站| 亚洲精品国模| 国产精品二区影院| 欧美丰满日韩| 国产精品99一区二区| 视频在线观看91| 日韩精品一区二区三区免费视频| 欧美一级久久| 中文在线а√天堂| 亚洲综合日韩| 国产精品99久久免费| 久久国产精品成人免费观看的软件| 亚洲一区亚洲| 欧美精品第一区| 国产一区观看| 久久国产精品免费一区二区三区 | 国产欧美一区二区色老头| av资源中文在线天堂| 美女毛片一区二区三区四区| 亚洲字幕久久| 高清av一区| 亚洲一区二区动漫| 国产精品a级| 中文精品在线| 精品国产精品久久一区免费式| 一区二区视频欧美| 欧美激情一区| 午夜国产精品视频免费体验区| 91精品在线免费视频| 日本综合字幕| 婷婷精品在线观看| 神马久久午夜| 欧美一级全黄| 欧美成人基地 | 精品国产aⅴ| 亚洲免费中文| 国产一区二区色噜噜| 在线视频精品| 欧美激情另类| 欧美在线看片| 在线国产一区二区| 久久精品国产福利| 丝袜亚洲另类欧美| 日韩欧美一区二区三区在线观看| 亚洲一区二区三区四区电影 | 国产超碰精品| 国产精品对白| 在线精品福利|