JAVA获取微信认证服务号openid、获取JS-SDK使用权限签名

获取微信认证服务号openid

官方文档

代码

通过code换取网页授权access_token
// 第二步:通过code换取网页授权access_token(网页授权token)
@RequestMapping("/getAccessToken")
public String getAccessToken(@RequestParam("code") String code, @RequestParam("openid") String openid) {
	RestResponse<WechatResult> resultRestResponse = new RestResponse<>();
	WechatResult result = new WechatResult();

	logger.info("请求参数:openid===>" + openid + ",code===>" + code);

	if (StringUtils.isBlank(code)) {
		resultRestResponse.setResMessage("code不能为空===>" + code);
		resultRestResponse.setRespCode(ErrorCode.INVALID_PARAMATER_ERROR);
		resultRestResponse.setData(result);
		return gson.toJson(resultRestResponse);
	}

	// 从redis缓存中取
	if (StringUtils.isNotBlank(openid) && redisTemplate.hasKey(openid)) {
		logger.info("openid过期时间===>" + redisTemplate.getExpire(openid) * 1000 + "毫秒");
		return redisTemplate.opsForValue().get(openid);
	}

	long millisecondNow = System.currentTimeMillis();
	// 获取网页授权token、openid
	String reqUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	reqUrl = reqUrl.replace("APPID", wechatAccountConfig.getAppid())
			.replace("SECRET", wechatAccountConfig.getSecret()).replace("CODE", code);
	String info = HttpsUtils.httpsRequest(reqUrl, "GET", null);
	logger.info("第二步:通过code获取openid,返回报文===>" + info);
	AuthorizationTokenDTO auToken = gson.fromJson(info, AuthorizationTokenDTO.class);
	if (auToken != null && StringUtils.isNotBlank(auToken.getOpenid())) {
		result.setOpenid(auToken.getOpenid());
		result.setAccessToken(auToken.getAccess_token());
	} else {
		resultRestResponse.setResMessage("获取openid===>" + info);
		resultRestResponse.setRespCode(ErrorCode.SERVER_ERROR);
		resultRestResponse.setData(result);
		return gson.toJson(resultRestResponse);
	}

	// 多減去5秒
	long millisecond = 7200000 - (System.currentTimeMillis() - millisecondNow) - 5000;
	resultRestResponse.setRespCode(RestResponse.SUCCESS_CODE);
	resultRestResponse.setData(result);
	resultRestResponse.setResMessage("请求成功");
	// 放入redis中,key为openid
	redisTemplate.opsForValue().set(result.getOpenid(), gson.toJson(resultRestResponse), millisecond,
			TimeUnit.MILLISECONDS);
	logger.info("放入redis成功,openid过期时间===>" + millisecond + "毫秒" + ",放入信息===>" + gson.toJson(resultRestResponse));
	return gson.toJson(resultRestResponse);
}
获取基础token
@RequestMapping("/getBasicToken")
public String getBasicToken() {
	return basicToken();
}

private String basicToken() {
	// 从redis缓存中取
	if (redisTemplate.hasKey(WX_BASIC_ACCESS_TOKEN)) {
		logger.info("WX_BASIC_ACCESS_TOKEN过期时间===>" + redisTemplate.getExpire(WX_BASIC_ACCESS_TOKEN) * 1000 + "毫秒");
		return redisTemplate.opsForValue().get(WX_BASIC_ACCESS_TOKEN);
	}
	long millisecondNow = System.currentTimeMillis();
	// 获取基础token(GET) 限200(次/天)
	String reqUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	reqUrl = reqUrl.replace("APPID", wechatAccountConfig.getAppid()).replace("APPSECRET",
			wechatAccountConfig.getSecret());
	String info = HttpsUtils.httpsRequest(reqUrl, "GET", null);
	logger.info("获取基础token,返回报文===>" + info);
	BasicTokenDTO token = gson.fromJson(info, BasicTokenDTO.class);
	String accessToken = "";
	if (token != null && token.getAccess_token() != null) {
		accessToken = token.getAccess_token();
	}
	// 访问超时,或者访问出错,accessToken为空时,不放入redis中
	if (StringUtils.isEmpty(accessToken)) {
		return accessToken;
	}
	// 多減去5秒
	long millisecond = 7200000 - (System.currentTimeMillis() - millisecondNow) - 5000;
	// 放入redis中,key为WX_BASIC_ACCESS_TOKEN
	redisTemplate.opsForValue().set(WX_BASIC_ACCESS_TOKEN, accessToken, millisecond, TimeUnit.MILLISECONDS);
	logger.info("放入redis成功,WX_BASIC_ACCESS_TOKEN过期时间===>" + millisecond + "毫秒" + ",accessToken===>" + accessToken);
	return accessToken;
}
刷新access_token
// 第三步:刷新access_token(如果需要)
@RequestMapping("/getRefreshToken")
public String getRefreshToken(@RequestParam("refreshToken") String refreshToken) {
	String reqUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
	reqUrl = reqUrl.replace("APPID", wechatAccountConfig.getAppid()).replace("REFRESH_TOKEN", refreshToken);
	String info = HttpsUtils.httpsRequest(reqUrl, "GET", null);
	logger.info("第三步:刷新access_token,返回报文===>" + info);
	return info;
}
拉取用户信息
// 第四步:拉取用户信息(需scope为 snsapi_userinfo)
@RequestMapping("/getUserInfo")
public String getUserInfo(@RequestParam("accessToken") String accessToken, @RequestParam("openId") String openId) {
	String reqUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
	reqUrl = reqUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
	String info = HttpsUtils.httpsRequest(reqUrl, "GET", null);
	return info;
}
生成授权链接
// 生成授权链接
@RequestMapping("/getAuthorizationLink")
public String getAuthorizationLink(@RequestParam("menuUrl") String menuUrl, @RequestParam("state") String state) {
	// 生成授权链接
	String authorizationLink = wxMpService.oauth2buildAuthorizationUrl(menuUrl,
			WxConsts.OAuth2Scope.SNSAPI_USERINFO, state);
	logger.info("生成授权链接===>" + authorizationLink);
	return authorizationLink;
}
发送模板消息
// 发送模板消息
// https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277
@RequestMapping("/sendTemplateMsg")
public String sendTemplateMsg(@RequestParam("data") String data) {
	String reqUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
	reqUrl = reqUrl.replace("ACCESS_TOKEN", getBasicToken());
	String info = HttpsUtils.httpsRequest(reqUrl, "POST", data);
	logger.info("发送模板消息接口,返回报文===>" + info);
	return info;
}

获取JS-SDK使用权限签名

官方文档

代码

获取JS-SDK使用权限签名
// 获取JS-SDK使用权限签名
// pageUrl:当前网页的URL,不包含#及其后面部分(例如:http://sto.natapp1.dd/index.html?code=061uUcfq1yKgkj0frceq1gi7fq1uUcfQ&state=123456)
@RequestMapping("/getSignature")
public String getSignature(@RequestParam("pageUrl") String pageUrl) {
	RestResponse<WechatResult> resultRestResponse = new RestResponse<>();
	WechatResult result = new WechatResult();

	logger.info("请求参数:pageUrl===>" + pageUrl);

	if (StringUtils.isBlank(pageUrl)) {
		resultRestResponse.setResMessage("pageUrl不能为空===>" + pageUrl);
		resultRestResponse.setRespCode(ErrorCode.INVALID_PARAMATER_ERROR);
		resultRestResponse.setData(result);
		return gson.toJson(resultRestResponse);
	}

	// 定义ticket变量
	String ticket = "";
	// 从redis缓存中取
	if (redisTemplate.hasKey(JSAPI_TICKET)) {
		logger.info("JSAPI_TICKET过期时间===>" + redisTemplate.getExpire(JSAPI_TICKET) * 1000 + "毫秒");
		ticket = redisTemplate.opsForValue().get(JSAPI_TICKET);
	}
	long millisecondNow = System.currentTimeMillis();
	// 采用http GET方式请求获得jsapi_ticket
	String reqUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	reqUrl = reqUrl.replace("ACCESS_TOKEN", basicToken());
	String info = HttpsUtils.httpsRequest(reqUrl, "GET", null);
	logger.info("获取jsapi_ticket,返回报文===>" + info);
	TicketDTO dto = gson.fromJson(info, TicketDTO.class);
	if (dto != null && StringUtils.isNotBlank(dto.getTicket())) {
		ticket = dto.getTicket();
		result.setTicket(ticket);
		// 多減去5秒
		long millisecond = 7200000 - (System.currentTimeMillis() - millisecondNow) - 5000;
		if (StringUtils.isNotBlank(ticket)) {
			// 放入redis中,key为JSAPI_TICKET
			redisTemplate.opsForValue().set(JSAPI_TICKET, ticket, millisecond, TimeUnit.MILLISECONDS);
		}
	} else {
		resultRestResponse.setResMessage("获取jsapi_ticket===>" + info);
		resultRestResponse.setRespCode(ErrorCode.SERVER_ERROR);
		resultRestResponse.setData(result);
		return gson.toJson(resultRestResponse);
	}

	// 时间戳和随机字符串
	String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
	String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
	// 将参数排序并拼接字符串
	String str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + pageUrl;
	// 将字符串进行sha1加密
	String signature = WechatUtil.SHA1(str);
	logger.info("参数===>" + str + ",签名===>" + signature);

	result.setTimestamp(timestamp);
	result.setNoncestr(noncestr);
	result.setSignature(signature);
	result.setAppId(wechatAccountConfig.getAppid());

	resultRestResponse.setRespCode(RestResponse.SUCCESS_CODE);
	resultRestResponse.setData(result);
	resultRestResponse.setResMessage("请求成功");
	logger.info("获取签名成功,返回信息===>" + gson.toJson(resultRestResponse));
	return gson.toJson(resultRestResponse);
}

工具类

代码

HttpsUtils
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
 * @author thebigdipperbdx
 * @description ${todo}
 * @date 2019-03-28 9:47
 */
public class HttpsUtils {
	private static Logger logger = Logger.getLogger(HttpsUtils.class);

	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
		// 初始化一个json对象
		String result = "";
		try {
			// 创建SSLContext对象,并使用我们指定的信任管理器初始化
			TrustManager[] tmManagers = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tmManagers, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory sslSocket = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
			httpsURLConnection.setSSLSocketFactory(sslSocket);

			//设置超时时间为10秒
			httpsURLConnection.setConnectTimeout(10000);
			httpsURLConnection.setReadTimeout(10000);

			httpsURLConnection.setDoOutput(true);
			httpsURLConnection.setDoInput(true);
			httpsURLConnection.setUseCaches(false);
			// 设置请求方式 GET/POST
			httpsURLConnection.setRequestMethod(requestMethod);
			// 不考虑大小写。如果两个字符串的长度相等,并且两个字符串中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。
			if ("GET".equalsIgnoreCase(requestMethod)) {
				httpsURLConnection.connect();
			}
			// 当有数据需要提交时,往服务器端写内容 也就是发起http请求需要带的参数
			if (StringUtils.isNotEmpty(outputStr)) {
				OutputStream outputStream = httpsURLConnection.getOutputStream();
				// 注意编码格式,防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 获得输入流 读取服务器端返回的内容
			InputStream inputStream = httpsURLConnection.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer stringBuffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				stringBuffer.append(str);
			}
			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			httpsURLConnection.disconnect();
			// 将字符串转换为json对象
			result = stringBuffer.toString();
		} catch (ConnectException ce) {
			logger.error("Weixin server connection timed out.");
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return result;
	}
}
MyX509TrustManager
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;

/**
 * @author thebigdipperbdx
 * @description ${todo}
 * @date 2019-03-28 9:50
 */
public class MyX509TrustManager implements X509TrustManager {
    /**
     * 该方法用于检查客户端的证书,若不信则抛出异常
     * 由于我们不需要对客户端进行认证,可以不做任何处理
     */
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateEncodingException{

    }
    /**
     * 该方法用于检验服务器端的证书,若不信任则抛出异常
     * 通过自己实现该方法,可以使之信任我们指定的任何证书
     * 在实现该方法时,也可以不做任何处理,即一个空的方法实现
     * 由于不会抛出异常,它就会信任任何证书
     */
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateEncodingException{

    }
    /**
     * 返回收信任的X509证书数组
     */
    @Override
    public X509Certificate[] getAcceptedIssuers(){
        return null;
    }
}
WechatMpConfig
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @author thebigdipperbdx
 * @description 
 * 参考文档:
 * 1、https://blog.csdn.net/qq_35164810/article/details/78710417
 * @date 2019-03-27 14:01
 */
@Component
public class WechatMpConfig {

    @Autowired
    private WechatAccountConfig wechatAccountConfig;

    // 首先将appid和secret放进一个WxMpService,创建一个WxMpService对象
    // 此注解指定在Spring容器启动时,就执行该方法并将该方法返回的对象交由Spring容器管理
    @Bean
    public WxMpService wxMpService(){
        //创建WxMpService实例并设置appid和sectret
        WxMpService wxMpService=new WxMpServiceImpl();
        // 设置配置信息的存储位置
        wxMpService.setWxMpConfigStorage(wxConfigProvider());
        return wxMpService;
    }

    @Bean
    public WxMpConfigStorage wxConfigProvider(){
        WxMpInMemoryConfigStorage wxConfigProvider=new WxMpInMemoryConfigStorage();
        wxConfigProvider.setAppId(wechatAccountConfig.getAppid());
        wxConfigProvider.setSecret(wechatAccountConfig.getSecret());
        return wxConfigProvider;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值