• H5链接分享到微信中形成小卡片(后端代码签名实现(超详细))


    获取token获取api_ticket,这个是用在签名里面的,直接调用就行;

    (这两个方法都写了缓存,和是失效时间,并且在用的时候都会去判断缓存里面有没有值,没有的话,我们再去请求重新获取,而不是每次都请求获取,这样会造成接口请求频繁受到限制的问题)

    1. @Component
    2. public class SignTicketUtils {
    3. @Autowired
    4. private WeiXinConfig weiXinConfig;
    5. @Autowired
    6. private RedisCache redisService;
    7. //公众号请求的地址
    8. public static String WX_GZH_API = "https://api.weixin.qq.com/cgi-bin/";
    9. /**
    10. * 第一步:获取access_token的值
    11. * @return
    12. */
    13. public String getToken() {
    14. String token = "";
    15. String path = "token?grant_type=client_credential&appid=" + weiXinConfig.getAppid() + "&secret=" + weiXinConfig.getSecret();
    16. String body = HttpUtils.sendGet(WX_GZH_API + path);
    17. JSONObject object = JSON.parseObject(body);
    18. //获取token
    19. token = object.getString("access_token");
    20. //将token值的值放在redis里面
    21. redisService.setCacheObject("gzh_access_token", token,7190, TimeUnit.SECONDS);
    22. return token;
    23. }
    24. /**
    25. * 第二步:获取jsapi_ticket
    26. * @return
    27. */
    28. public String getJsapiTicket() {
    29. //获取redis里面的token
    30. Object access_token = redisService.getCacheObject("gzh_access_token");
    31. if (access_token==null) {
    32. access_token = getToken();
    33. }
    34. String path = "ticket/getticket?access_token=" + access_token.toString() + "&type=jsapi";
    35. String body = HttpUtils.sendGet(WX_GZH_API + path);
    36. JSONObject object = JSON.parseObject(body);
    37. //获取ticket
    38. String ticket = object.getString("ticket");
    39. //错误码
    40. Integer errcode = object.getInteger("errcode");
    41. if(errcode==0){
    42. //将ticket值的值放在redis里面
    43. redisService.setCacheObject("gzh_ticket", ticket,7190,TimeUnit.SECONDS);
    44. }
    45. return ticket;
    46. }
    47. /**
    48. * 公众号网页开发
    49. * @param jsapi_ticket
    50. * @param url
    51. * @return
    52. */
    53. public static Map sign(String jsapi_ticket, String url) {
    54. Map ret = new HashMap();
    55. String nonce_str = create_nonce_str();
    56. String timestamp = create_timestamp();
    57. String string1;
    58. String signature = "";
    59. //注意这里参数名必须全部小写,且必须有序
    60. string1 = "jsapi_ticket=" + jsapi_ticket +
    61. "&noncestr=" + nonce_str +
    62. "×tamp=" + timestamp +
    63. "&url=" + url;
    64. System.out.println(string1);
    65. try
    66. {
    67. MessageDigest crypt = MessageDigest.getInstance("SHA-1");
    68. crypt.reset();
    69. crypt.update(string1.getBytes("UTF-8"));
    70. signature = byteToHex(crypt.digest());
    71. }
    72. catch (NoSuchAlgorithmException | UnsupportedEncodingException e)
    73. {
    74. e.printStackTrace();
    75. }
    76. ret.put("url", url);
    77. ret.put("jsapi_ticket", jsapi_ticket);
    78. ret.put("nonceStr", nonce_str);
    79. ret.put("timestamp", timestamp);
    80. ret.put("signature", signature);
    81. return ret;
    82. }
    83. private static String byteToHex(final byte[] hash) {
    84. Formatter formatter = new Formatter();
    85. for (byte b : hash)
    86. {
    87. formatter.format("%02x", b);
    88. }
    89. String result = formatter.toString();
    90. formatter.close();
    91. return result;
    92. }
    93. private static String create_nonce_str() {
    94. return UUID.randomUUID().toString();
    95. }
    96. private static String create_timestamp() {
    97. return Long.toString(System.currentTimeMillis() / 1000);
    98. }
    99. }

     获取签名 

    1. @Api("微信分享")
    2. @RestController
    3. @RequestMapping("/自己的路径")
    4. public class SignTicketController {
    5. @Autowired
    6. private RedisCache redisService;
    7. @Autowired
    8. private WeiXinConfig weiXinConfig;
    9. @Autowired
    10. private SignTicketUtils signTicketUtils;
    11. /**
    12. * 开始签名
    13. */
    14. @GetMapping("/getSign")
    15. public R getSign(String url){
    16. //从redis里面获取ticket
    17. Object ticket = redisService.getCacheObject("gzh_ticket");
    18. if(ticket==null){
    19. ticket = signTicketUtils.getJsapiTicket();
    20. }
    21. Map ret = signTicketUtils.sign(ticket.toString(), url);
    22. JSONObject objectData = new JSONObject();
    23. for (Map.Entry entry : ret.entrySet()) {
    24. objectData.put(entry.getKey().toString(),entry.getValue());
    25. }
    26. objectData.put("appId", weiXinConfig.getAppid());
    27. return R.ok(objectData);
    28. }
    29. }

     返回结果集类(可用自己的,附上仅为了复制代码直接可用)

    1. public class R implements Serializable
    2. {
    3. private static final long serialVersionUID = 1L;
    4. /** 成功 */
    5. public static final int SUCCESS = HttpStatus.SUCCESS;
    6. /** 失败 */
    7. public static final int FAIL = HttpStatus.ERROR;
    8. private int code;
    9. private String msg;
    10. private T data;
    11. public static R ok()
    12. {
    13. return restResult(null, SUCCESS, "操作成功");
    14. }
    15. public static R ok(T data)
    16. {
    17. return restResult(data, SUCCESS, "操作成功");
    18. }
    19. public static R ok(T data, String msg)
    20. {
    21. return restResult(data, SUCCESS, msg);
    22. }
    23. public static R fail()
    24. {
    25. return restResult(null, FAIL, "操作失败");
    26. }
    27. public static R fail(String msg)
    28. {
    29. return restResult(null, FAIL, msg);
    30. }
    31. public static R fail(T data)
    32. {
    33. return restResult(data, FAIL, "操作失败");
    34. }
    35. public static R fail(T data, String msg)
    36. {
    37. return restResult(data, FAIL, msg);
    38. }
    39. public static R fail(int code, String msg)
    40. {
    41. return restResult(null, code, msg);
    42. }
    43. private static R restResult(T data, int code, String msg)
    44. {
    45. R apiResult = new R<>();
    46. apiResult.setCode(code);
    47. apiResult.setData(data);
    48. apiResult.setMsg(msg);
    49. return apiResult;
    50. }
    51. public int getCode()
    52. {
    53. return code;
    54. }
    55. public void setCode(int code)
    56. {
    57. this.code = code;
    58. }
    59. public String getMsg()
    60. {
    61. return msg;
    62. }
    63. public void setMsg(String msg)
    64. {
    65. this.msg = msg;
    66. }
    67. public T getData()
    68. {
    69. return data;
    70. }
    71. public void setData(T data)
    72. {
    73. this.data = data;
    74. }
    75. public static Boolean isError(R ret)
    76. {
    77. return !isSuccess(ret);
    78. }
    79. public static Boolean isSuccess(R ret)
    80. {
    81. return R.SUCCESS == ret.getCode();
    82. }
    83. }

  • 相关阅读:
    无公网IP通过旁路由openwrt的Zerotier实现和在家一样访问家里每个设备
    CrossOver2023(Mac电脑运行Windows软件)
    Vue——多页面不共用token进行拦截
    OceanBase TableAPI实践案例(Java)
    声学特征提取
    报错 throw er; // Unhandled ‘error‘ event
    docke部署nodejs程序及Dockerfile详解
    Python综合案例(基本地图使用)
    数据同步、
    Windows 11 Manager v1.1.8 系统优化工具中文便携版
  • 原文地址:https://blog.csdn.net/sinat_21843047/article/details/133886009