news 2026/4/15 13:45:06

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/4/15 8:36:11

从零搭建量子计算开发环境:镜像缓存构建的4个核心原则与实操技巧

第一章&#xff1a;量子计算开发环境概述量子计算作为下一代计算范式的前沿领域&#xff0c;其开发环境的搭建是进入该领域的第一步。与传统软件开发不同&#xff0c;量子计算依赖于特定的量子编程框架和模拟器&#xff0c;以支持量子比特操作、量子线路构建以及结果测量等核心…

作者头像 李华
网站建设 2026/4/14 0:22:34

针对一个嵌入式AI视觉http后端系统的设计

AI视觉后端系统详细设计文档 个人专著《C++元编程与通用设计模式实现》由清华大学出版社出版。该书内容源于工业级项目实践,出版后市场反馈积极(已加印)。其专业价值获得了图书馆系统的广泛认可:不仅被中国国家图书馆作为流通与保存本收藏,还被近半数省级公共图书馆及清华…

作者头像 李华
网站建设 2026/4/11 13:54:20

HTTP 无状态与 Cookie 状态保持机制详解

HTTP 无状态与 Cookie 状态保持机制详解 一、背景&#xff1a;HTTP 真的是“无状态”吗&#xff1f; HTTP 被称为无状态协议&#xff0c;并不是说它完全无法“记住”用户&#xff0c;而是&#xff1a; 每一次 HTTP 请求在协议层面都是相互独立的服务器不会天然保存客户端的上下…

作者头像 李华
网站建设 2026/4/12 13:22:44

计算机网络基础

网络定义 多台设备通过连接介质&#xff0c;能互相传数据&#xff0c;共享资源的集合 协议&#xff1a;设备之间的沟通规则 拓扑结构 网络设备的物理连接方式 星型&#xff1a;就是有一个中间的设备转一下 总线型&#xff1a;学校机房那种所有设备连着一台设备 环型&#xff1a…

作者头像 李华
网站建设 2026/4/11 12:56:34

AI智能体(Agent)开发全攻略:概念、设计到安全运行,程序员必学

本文详解AI智能体的本质区别、三大核心特征及落地路径&#xff0c;涵盖模型选型、工具定义、指令配置等关键组件&#xff0c;解析单智能体与多智能体编排模式&#xff0c;并强调安全护栏体系的重要性&#xff0c;为开发者提供从0到1构建智能体的完整路线图&#xff0c;助力抢占…

作者头像 李华
网站建设 2026/4/11 9:33:45

LLM RAG开发进阶:多查询检索技术详解与实战代码

本文详细介绍了LLM应用中RAG开发的三个关键步骤和六个优化阶段&#xff0c;重点阐述了多查询检索策略如何提升检索准确性。通过生成多个角度的子问题进行检索并合并结果&#xff0c;有效克服传统相似性搜索的局限。文章提供了LangChain中MultiQueryRetriever的具体实现代码和优…

作者头像 李华