场景:户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录。
逻辑:
- 系统生成带参数的临时二维码:参数 scene_str 自定义为唯一值(可以是uuid),临时二维码的生成方式参照官方接口的开发文档
- 用户使用微信扫描该二维码,关注后微信服务器会将关注事件的响应数据返回给我们的应用服务器:微信通过我们在公众号配置的“服务器地址(URL)”,将响应数据返回给我们的应用服务器,响应数据包括 参数 scene_str 和 openid
- 应用服务器将接收到的openid再次向微信服务器发起请求,获取该用户的信息(昵称、头像、地域、unionid(若绑定了微信开放平台,则有此参数))
- 将返回的信息存储到数据库,用于登录:特别是 scene_str 也要记录,因为需要根据这个唯一值来判断当前是谁在扫描关注并登录
准备工作:登录微信公众号平台,在基本配置下获取 AppID,AppSecret,“服务器地址(URL)”即“回调函数”,令牌Token。如下图:
本人用的开发框架是 springboot,代码如下:
- 后台代码:
- HttpClientKit.java:封装https请求,调用微信接口
package com.ht.website.utils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URL; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import com.alibaba.fastjson.JSONObject; public class HttpClientKit { /** * https请求信任管理器 * @author Timely-03 */ private static class TrustAnyTrustManager implements X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } } /** * 发送https请求 */ private static JSONObject https(String requestUrl, String requestMethod, String submitData) { HttpsURLConnection httpsURLCon = null; try { // 设置https访问模式,采用SSL加密 TrustManager[] tm = { new TrustAnyTrustManager() }; // 创建SSLContext对象,并使用我们指定的信任管理器初始化 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从sslContext获取SSLSocketFactory SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); httpsURLCon = (HttpsURLConnection) url.openConnection(); httpsURLCon.setSSLSocketFactory(ssf); httpsURLCon.setDoInput(true); httpsURLCon.setDoOutput(true); httpsURLCon.setUseCaches(false); httpsURLCon.setRequestMethod(requestMethod);// 设置请求方式get;post if ("GET".equalsIgnoreCase(requestMethod)) { httpsURLCon.connect(); } // 当需要有数据提交给微信接口时 if (submitData != null) { OutputStream outputStream = httpsURLCon.getOutputStream(); outputStream.write(submitData.getBytes(WSConst.ENCODE_UTF_8)); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = httpsURLCon.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, WSConst.ENCODE_UTF_8); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; httpsURLCon.disconnect(); return JSONObject.parseObject(buffer.toString()); } catch (Exception e) { throw new RuntimeException(e); } finally { if (httpsURLCon != null) { httpsURLCon.disconnect(); } } } /** * 发送https请求,请求方法:POST * @param requestUrl 请求地址,比如:https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token= * @param submitData 提交参数 * @return 返回请求结果字符串 */ public static JSONObject httpsPost(String requestUrl, String submitData) { return https(requestUrl, "POST", submitData); } /** * 发送https请求,请求方法:GET * @param requestUrl 请求地址,比如:https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token= * @param submitData 提交参数 * @return 返回请求结果字符串 */ public static JSONObject httpsGet(String requestUrl, String submitData) { return https(requestUrl, "GET", submitData); } }
- application.properties:配置微信appid,appSecret
- HttpClientKit.java:封装https请求,调用微信接口