news 2026/2/8 2:46:18

Java微信分享-签名算法实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java微信分享-签名算法实现

文章目录

  • 前言

前言

  1. 工具类 - WxJsapiSignature.java
importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.UUID;publicclassWxJsapiSignature{/** * 生成微信 JS-SDK 签名 * @param jsapiTicket 微信 jsapi_ticket * @param url 当前页面 URL(不包含 # 后面的部分) * @return 签名信息对象 */publicstaticSignatureResultgenerateSignature(StringjsapiTicket,Stringurl){// 生成随机字符串StringnonceStr=createNonceStr();// 生成时间戳(秒)longtimestamp=System.currentTimeMillis()/1000;// 按字典序拼接字符串Stringstring1="jsapi_ticket="+jsapiTicket+"&noncestr="+nonceStr+"&timestamp="+timestamp+"&url="+url;// SHA1 加密Stringsignature=sha1(string1);// 返回结果SignatureResultresult=newSignatureResult();result.setNonceStr(nonceStr);result.setTimestamp(timestamp);result.setSignature(signature);returnresult;}/** * SHA1 加密 */privatestaticStringsha1(Stringstr){try{MessageDigestdigest=MessageDigest.getInstance("SHA-1");digest.update(str.getBytes());byte[]messageDigest=digest.digest();// 转换为十六进制字符串StringBuilderhexString=newStringBuilder();for(byteb:messageDigest){Stringhex=Integer.toHexString(0xFF&b);if(hex.length()==1){hexString.append('0');}hexString.append(hex);}returnhexString.toString();}catch(NoSuchAlgorithmExceptione){thrownewRuntimeException("SHA1 加密失败",e);}}/** * 生成随机字符串 */privatestaticStringcreateNonceStr(){returnUUID.randomUUID().toString().replace("-","").substring(0,16);}}
  1. 签名结果类 - SignatureResult.java
publicclassSignatureResult{privateStringnonceStr;privateLongtimestamp;privateStringsignature;// Getters and SetterspublicStringgetNonceStr(){returnnonceStr;}publicvoidsetNonceStr(StringnonceStr){this.nonceStr=nonceStr;}publicLonggetTimestamp(){returntimestamp;}publicvoidsetTimestamp(Longtimestamp){this.timestamp=timestamp;}publicStringgetSignature(){returnsignature;}publicvoidsetSignature(Stringsignature){this.signature=signature;}}
  1. Controller 示例
importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/wechat")publicclassWechatController{@AutowiredprivateWechatServicewechatService;/** * 获取微信 JS-SDK 签名 */@PostMapping("/jsapi-signature")publicResultgetJsapiSignature(@RequestBodySignatureRequestrequest){try{Stringurl=request.getUrl();// 1. 获取 access_token(需要缓存,有效期 7200 秒)StringaccessToken=wechatService.getAccessToken();// 2. 获取 jsapi_ticket(需要缓存,有效期 7200 秒)StringjsapiTicket=wechatService.getJsapiTicket(accessToken);// 3. 生成签名SignatureResultsignature=WxJsapiSignature.generateSignature(jsapiTicket,url);// 4. 返回结果Map<String,Object>data=newHashMap<>();data.put("appId",wechatService.getAppId());data.put("timestamp",signature.getTimestamp());data.put("nonceStr",signature.getNonceStr());data.put("signature",signature.getSignature());returnResult.success(data);}catch(Exceptione){returnResult.error("获取签名失败: "+e.getMessage());}}}
  1. Service 示例(获取 access_token 和 jsapi_ticket)
importorg.springframework.stereotype.Service;importorg.springframework.web.client.RestTemplate;importcom.alibaba.fastjson.JSONObject;@ServicepublicclassWechatService{@Value("${wechat.appId}")privateStringappId;@Value("${wechat.appSecret}")privateStringappSecret;@AutowiredprivateRestTemplaterestTemplate;// 缓存 access_token(实际项目中应该用 Redis 缓存)privateStringcachedAccessToken;privatelongaccessTokenExpireTime;// 缓存 jsapi_ticketprivateStringcachedJsapiTicket;privatelongjsapiTicketExpireTime;/** * 获取 access_token */publicStringgetAccessToken(){// 检查缓存if(cachedAccessToken!=null&&System.currentTimeMillis()<accessTokenExpireTime){returncachedAccessToken;}// 请求微信接口Stringurl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;Stringresponse=restTemplate.getForObject(url,String.class);JSONObjectjson=JSONObject.parseObject(response);if(json.containsKey("access_token")){cachedAccessToken=json.getString("access_token");// 提前 5 分钟过期accessTokenExpireTime=System.currentTimeMillis()+(json.getInteger("expires_in")-300)*1000;returncachedAccessToken;}else{thrownewRuntimeException("获取 access_token 失败: "+response);}}/** * 获取 jsapi_ticket */publicStringgetJsapiTicket(StringaccessToken){// 检查缓存if(cachedJsapiTicket!=null&&System.currentTimeMillis()<jsapiTicketExpireTime){returncachedJsapiTicket;}// 请求微信接口Stringurl="https://api.weixin.qq.com/cgi-bin/ticket/getjsapi_ticket?access_token="+accessToken;Stringresponse=restTemplate.getForObject(url,String.class);JSONObjectjson=JSONObject.parseObject(response);if(json.getInteger("errcode")==0){cachedJsapiTicket=json.getString("ticket");// 提前 5 分钟过期jsapiTicketExpireTime=System.currentTimeMillis()+(json.getInteger("expires_in")-300)*1000;returncachedJsapiTicket;}else{thrownewRuntimeException("获取 jsapi_ticket 失败: "+response);}}publicStringgetAppId(){returnappId;}}
  1. 请求对象
publicclassSignatureRequest{privateStringurl;publicStringgetUrl(){returnurl;}publicvoidsetUrl(Stringurl){this.url=url;}}
  1. application.yml 配置
wechat: appId: wxf123456789 appSecret: your_app_secret_here

关键点:
SHA1 加密必须转换为小写十六进制字符串
参数拼接顺序必须是字典序:jsapi_ticket、noncestr、timestamp、url
URL 不能 encode,保持原样
access_token 和 jsapi_ticket 必须缓存,避免频繁请求导致限流
时间戳单位是秒,不是毫秒

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 21:48:52

机器学习算法:随机梯度下降算法

目录 动量法 是什么&#xff1f; 从数学上理解 案例&#xff1a;寻找最佳学习节奏 公式推导与解析 1. 基础梯度下降回顾 2. 引入动量项 3. 物理意义与优势 扩展&#xff1a;NAG (Nesterov Accelerated Gradient) 优缺点和适用场景 完整代码示例&#xff1a;在回归问题…

作者头像 李华
网站建设 2026/2/7 23:05:52

极端天气频发,我们该如何应对?,基于R语言的气象归因分析全流程解析

第一章&#xff1a;气象数据的 R 语言极端事件归因 在气候变化研究中&#xff0c;极端天气事件的归因分析是评估人类活动对气候影响的关键手段。R 语言凭借其强大的统计建模与可视化能力&#xff0c;成为处理气象时间序列数据和开展归因研究的首选工具。通过整合观测数据、气候…

作者头像 李华
网站建设 2026/2/7 15:55:26

从开发到生产:构建全链路可信Agent的镜像签名体系

第一章&#xff1a;从开发到生产&#xff1a;构建全链路可信Agent的镜像签名体系在现代云原生架构中&#xff0c;Agent作为连接控制平面与工作负载的核心组件&#xff0c;其安全性直接影响整个系统的可信边界。为确保从开发、构建到部署全流程中Agent镜像的完整性与来源可信&am…

作者头像 李华
网站建设 2026/2/6 10:07:44

R语言农业产量模型评估,掌握这4个关键步骤让你少走10年弯路

第一章&#xff1a;R语言农业产量模型评估概述在现代农业数据分析中&#xff0c;利用统计建模预测作物产量已成为优化资源配置与提升生产效率的关键手段。R语言凭借其强大的统计计算能力和丰富的可视化工具&#xff0c;成为农业科研人员构建和评估产量模型的首选平台。通过整合…

作者头像 李华
网站建设 2026/2/7 22:15:28

第15章 标准IO:重定向和管道

从一开始&#xff0c;Unix 命令行就具备一些特殊的东西&#xff0c;使其区别与其他操作系统&#xff0c;即所谓的的 Unix工具箱&#xff1a;每种 Unix 和 Linux 系统都拥有的大量程序。本章将解释 Unix 工具箱之后隐藏的设计准则&#xff0c;然后师范如何将基本的构建块组合成适…

作者头像 李华
网站建设 2026/2/6 23:41:32

BGP实验基础配置

实验拓扑实验要求 1、AS1中存在两个环回&#xff0c;一个地址为192.168.1.0/24&#xff0c;该地址不能在任何协议中宣告AS3中存在两个环回&#xff0c;一个地址为192.168.2.0/24&#xff0c;该地址不能在任何协议中宣告&#xff0c;最终要求这两个环回可以ping通2、R1-R8的建邻…

作者头像 李华