Java实现微信扫一扫功能获取签名

2 篇文章 0 订阅

目录

一、流程:

二、分步骤解析:

1)获取token

2)拿token获取ticket

3)获取随机字符串(用自带的UUID就行)

4)获取当前时间戳,记得除以1000(10位数) 例如:1626139722

5)、6)拼接参数,并加密

三、完整代码:

四、总结


一、流程:

1) 前端请求后台接口,传入url

2) 后端接收请求,处理业务逻辑,返回签名等参数

1.获取token

2.拿token获取ticket

3.获取随机字符串(用自带的UUID就行)

4.获取当前时间戳,记得除以1000(10位数) 例如:1626139722

5.拼接参数(url是前端传过来的)

        String context = "jsapi_ticket=xxxx&noncestr=xxxx&timestamp=xxxx&url=xxxx“

6.参数SHA1加密

7.封装,返回前端

二、分步骤解析:

如果不想了解,直接去最下面Cope完整代码

1)获取token

appid、secret、grant_type这三个值都是固定值

前两个值是微信公众号开发者平台上的凭据,AppId 和 AppSecret

微信公众平台凭据调试工具:微信公众平台接口调试工具

------------------------------------------------------------------------------------------------------------

appid:公众号的id

secret:公众号的秘钥

grant_type:授权码发放类型(固定值:client_credential

        grant_type=client_credential

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

private static JsonParser parse = new JsonParser();


/**
 * 获取 token
 * @return
 */
public static String getToken() {
	// https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxxx&secret=xxxx
	String url = ACCESS_TOKEN_URL + "?grant_type=" + GRANT_TYPE + "&appid=" + APPID + "&secret=" + SECRET;
	//请求链接获取token,这个httpGetForJson()方法去完整代码中找
	String response = httpGetForJson(url);
	return ((JsonObject) parse.parse(response)).get(ACCESS_TOKEN_KEY).getAsString();
}

2)拿token获取ticket

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

private static JsonParser parse = new JsonParser();


/**
 * 获取 ticket
 * @param token
 * @return
 */
public static String getTicket(String token) {
	// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=xxxx&type=jsapi
	String url = TICKET_URL + "?access_token=" + token + "&type=" + TYPE;
	//请求链接获取token,这个httpGetForJson()方法去完整代码中找
	String response = httpGetForJson(url);
	return ((JsonObject) parse.parse(response)).get(TICKET_KEY).getAsString();
}

3)获取随机字符串(用自带的UUID就行)

import java.util.UUID;

String nonceStr = UUID.randomUUID().toString();

4)获取当前时间戳,记得除以1000(10位数) 例如:1626139722

String timestamp = Long.toString(System.currentTimeMillis() / 1000);

5)、6)拼接参数,并加密

微信 JS 接口签名校验工具:微信 JS 接口签名校验工具

// 值是前几步骤中获取到的,url是前端传过来的
String context = "jsapi_ticket=xxxx&noncestr=xxxx&timestamp=xxxx&url=xxxx";

//加密
String signature = SHA1(context);
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * SHA1加密
 * @param value
 * @return
 */
public static String SHA1(final String value) {
	MessageDigest digest;
	try {
		digest = MessageDigest.getInstance("SHA-1");
		digest.update(value.getBytes());
		byte messageDigest[] = digest.digest();
		StringBuffer hexString = new StringBuffer();
		for (int i = 0; i < messageDigest.length; i++) {
			String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
			if (shaHex.length() < 2) {
				hexString.append(0);
			}
			hexString.append(shaHex);
		}
		return hexString.toString();
	} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
	}
	return "";
}

三、完整代码:

直接拿来用,前端传入url直接请求

返回类型自己封装个就行,不一定直接返回Map<String, String>

WxSignatureUtil是自己封装的微信生成签名工具类

import com.smart.wechat.config.WxSignatureUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

@RestController
@RequestMapping("/wx/config")
public class WxConfigController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 获取微信配置
     * params:前端传过来的,包含url
     */
    @RequestMapping("/gerWxConfig")
    public Map<String, String> gerWxConfig(@RequestBody Map<String,Object> params) {
        try {
            String url = String.valueOf(params.get("url"));
            Map<String, String> returnMap = WxSignatureUtil.getWechatSignature(url);
            return returnMap;
        } catch (Exception e) {
            return null;
        }
    }


}
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Component
public class WxSignatureUtil {

    /**
     * 开发者ID,必填
     * 微信公众号开发者平台上的凭据 AppId
     */
    private static fianl String APPID = "xxxxxxxx";
    /**
     * 开发者秘钥,必填
     * 微信公众号开发者平台上的凭据 AppSecret
     */
    private static fianl String SECRET = "xxxxxxxx";
    /**
     * 授权码发放类型
     */
    private static final String GRANT_TYPE = "client_credential";
    /**
     * 授权码类型
     */
    private static final String TYPE = "jsapi";
    /**
     * 获取微信 TOKEN 接口
     */
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    /**
     * 获取微信令牌接口
     */
    private static final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
    /**
     * 请求参数名
     */
    private static final String ACCESS_TOKEN_KEY = "access_token";
    /**
     * TICKET_KEY
     */
    private static final String TICKET_KEY = "ticket";
    /**
     * JSON 解析
     */
    private static JsonParser parse = new JsonParser();

    /**
     * 获取签名
     * 注意 URL 一定要动态获取,不能 hardcode
     * @param url
     * @return
     */
    public static Map<String, String> getWechatSignature(String url) {
        // 获取token
        String token = getToken();
        // 获取ticket
        String ticket = getTicket(token);
        // 随机字符串
        String nonceStr = UUID.randomUUID().toString();
        // 时间戳
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        //注意这里参数名必须全部小写,且必须有序
        String context = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url;
        //加密
        String signature = SHA1(context);
        //封装
        Map<String, String> result = new HashMap<String, String>();
        result.put("url", url);
        result.put("jsapi_ticket", ticket);
        result.put("nonceStr", nonceStr);
        result.put("timestamp", timestamp);
        result.put("signature", signature);
        result.put("appId", APPID);
        return result;
    }

    /**
     * 获取 token
     * @return
     */
    public static String getToken() {
        // https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=xxxxxxxxx
        String url = ACCESS_TOKEN_URL + "?grant_type=" + GRANT_TYPE + "&appid=" + APPID + "&secret=" + SECRET;
        //请求链接获取token
        String response = httpGetForJson(url);
        return ((JsonObject) parse.parse(response)).get(ACCESS_TOKEN_KEY).getAsString();
    }

    /**
     * 获取 ticket
     * @param token
     * @return
     */
    public static String getTicket(String token) {
        // https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=xxxx&type=jsapi
        String url = TICKET_URL + "?access_token=" + token + "&type=" + TYPE;
        //请求链接获取token
        String response = httpGetForJson(url);
        return ((JsonObject) parse.parse(response)).get(TICKET_KEY).getAsString();
    }

    /**
     * SHA1加密
     * @param value
     * @return
     */
    public static String SHA1(final String value) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-1");
            digest.update(value.getBytes());
            byte messageDigest[] = digest.digest();
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 发送请求
     * @param url
     * @return
     */
    public static String httpGetForJson(String url) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            // 创建 HTTPGET
            HttpGet httpget = new HttpGet(url);
            // 发送 GET 请求
            CloseableHttpResponse response = httpclient.execute(httpget);
            HttpEntity entity = response.getEntity();
            return entity == null ? "" : EntityUtils.toString(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

}

四、总结

需要前端多配合,校验工具不一定准确,仅供参考,避坑!!!

问题:

还有一个前端的坑:就是微信公众平台微信公众平台:添加配置,JS接口安全域名,微信扫一扫才能拉起来

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学弟不想努力了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值