微信公众测试号授权登录 学习笔记
先看看时序图
- 公众测试号申请
- 网页登录授权步骤
- java登录案例
- 第一步
- 第二步
- 第三步
公众测试号申请
这里以测试号为基础进行学习
首先微信进入微信公众平台
登录后填写接口配置信息,这步可以先不填,等后台写好代码再回来填写
点击接口权限表下的网页授权获取用户基本信息的修改,然后填写域名(请勿加 http:// 等协议头)
扫描关注
网页登录授权步骤
开始授权获取用户信息,具体而言,网页授权流程分为四步:
1、引导用户进入授权页面同意授权,获取code
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
3、如果需要,开发者可以刷新网页授权access_token,避免过期
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
具体步骤看 网页授权文档 按着他步骤来
- 我们以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
- 让用户点击以下链接或扫携带此连接的二维码,此链接要修改以下三处地方appid,redirect_uri,state
https://open.weixin.qq.com/connect/oauth2/authorize?appid=自己的appID&redirect_uri=需要跳转的页面&response_type=code&scope=snsapi_userinfo&state=需要携带的参数#wechat_redirect - 用户同意授权后
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=携带的参数。
code说明 :
code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。 - 获取code后,填写appid,secret,code参数,请求以下链接获取access_token和openid: https://api.weixin.qq.com/sns/oauth2/access_token?appid=自己的appID&secret=自己公众测试号的appsecret&code=获取的code&grant_type=authorization_code
- 通过access_token和openid获取用户信息
GET请求 https://api.weixin.qq.com/sns/userinfo?access_token=获取的ACCESS_TOKEN&openid=获取的OPENID&lang=zh_CN
请求成功后返回以下用户信息参数 描述 openid 用户的唯一标识 nickname 用户昵称 sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 province 用户个人资料填写的省份 city 普通用户个人资料填写的城市 country 国家,如中国为CN headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
java登录案例
第一步
我们得回到公众测试号申请第二步进行接口配置,具体查看 消息接口使用指南
以下是验证代码,访问以下接口,检验signature对请求进行校验。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
@Controller
public class WechatController {@GetMapping("/wechat")public void doGet(HttpServletRequest request, HttpServletResponse response) {// 微信加密签名String signature = request.getParameter("signature");// 时间戳String timestamp = request.getParameter("timestamp");// 随机数String nonce = request.getParameter("nonce");// 随机字符串String echostr = request.getParameter("echostr");// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败PrintWriter out = null;try {out = response.getWriter();if (SignUtil.checkSignature(signature, timestamp, nonce)) {out.print(echostr);}} catch (IOException e) {e.printStackTrace();} finally {if (out != null) {out.close();}}}
}
微信请求校验工具类
/*** 微信请求校验工具类*/
public class SignUtil {// 与接口配置信息中的Token要一致private static String token = "o2o";/*** 验证签名** @param signature* @param timestamp* @param nonce* @return*/public static boolean checkSignature(String signature, String timestamp, String nonce) {String[] arr = new String[]{token, timestamp, nonce};// 将token、timestamp、nonce三个参数进行字典序排序Arrays.sort(arr);StringBuilder content = new StringBuilder();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}MessageDigest md = null;String tmpStr = null;try {md = MessageDigest.getInstance("SHA-1");// 将三个参数字符串拼接成一个字符串进行sha1加密byte[] digest = md.digest(content.toString().getBytes());tmpStr = byteToStr(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}content = null;// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;}/*** 将字节数组转换为十六进制字符串** @param byteArray* @return*/private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}/*** 将字节转换为十六进制字符串** @param mByte* @return*/private static String byteToHexStr(byte mByte) {char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}
}
第二步
准备请求工具类,接收返回结果的实体类等等
上面网页登录授权的具体步骤:第四步中主要接收access_token和openid的实体类
/*** 用户授权token*/
@Data
public class UserAccessToken {// 获取到的凭证@JsonProperty("access_token")private String accessToken;// 凭证有效时间,单位:秒@JsonProperty("expires_in")private String expiresIn;// 表示更新令牌,用来获取下一次的访问令牌,这里没太大用处@JsonProperty("refresh_token")private String refreshToken;// 该用户在此公众号下的身份标识,对于此微信号具有唯一性@JsonProperty("openid")private String openId;// 表示权限范围,这里可省略@JsonProperty("scope")private String scope;
}
最后返回的用户信息类
@Data
public class WechatUser implements Serializable {private static final long serialVersionUID = 1L;// openId,标识该公众号下面的该用户的唯一Id@JsonProperty("openid")private String openId;// 用户昵称@JsonProperty("nickname")private String nickName;// 性别@JsonProperty("sex")private int sex;// 省份@JsonProperty("province")private String province;// 城市@JsonProperty("city")private String city;// 区@JsonProperty("country")private String country;// 头像图片地址@JsonProperty("headimgurl")private String headimgurl;// 语言@JsonProperty("language")private String language;// 用户权限,这里没什么作用@JsonProperty("privilege")private String[] privilege;
}
证书信任管理器(用于https请求)
/*** 证书信任管理器(用于https请求)*/
public class MyX509TrustManager implements X509TrustManager {public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public X509Certificate[] getAcceptedIssuers() {return null;}
}
请求工具接收返回结果
public class WechatUtil {/*** 获取UserAccessToken实体类*/public static UserAccessToken getUserAccessToken(String code) throws IOException {// 测试号信息里的appIdString appId = "填上";// 测试号信息里的appsecretString appsecret = "填上";// 根据传入的code,拼接出访问微信定义好的接口的URLString url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appsecret+ "&code=" + code + "&grant_type=authorization_code";// 向相应URL发送请求获取token json字符串String tokenStr = httpsRequest(url, "GET", null);UserAccessToken token = new com.yhy.o2o.utils.weixin.message.pojo.UserAccessToken();ObjectMapper objectMapper = new ObjectMapper();try {// 将json字符串转换成相应对象token = objectMapper.readValue(tokenStr, UserAccessToken.class);} catch (Exception e) {e.printStackTrace();} if (token == null) {return null;}return token;}/*** 获取WechatUser实体类*/public static WechatUser getUserInfo(String accessToken, String openId) {// 根据传入的accessToken以及openId拼接出访问微信定义的端口并获取用户信息的URLString url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId+ "&lang=zh_CN";// 访问该URL获取用户信息json 字符串String userStr = httpsRequest(url, "GET", null);WechatUser user = new com.yhy.o2o.utils.weixin.WechatUser();ObjectMapper objectMapper = new ObjectMapper();try {// 将json字符串转换成相应对象user = objectMapper.readValue(userStr, com.yhy.o2o.utils.weixin.WechatUser.class);} catch (Exception e) {e.printStackTrace();} if (user == null) {return null;}return user;}/*** 发起https请求并获取结果** @param requestUrl 请求地址* @param requestMethod 请求方式(GET、POST)* @param outputStr 提交的数据* @return json字符串*/public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {StringBuffer buffer = new StringBuffer();try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = {new com.yhy.o2o.utils.weixin.MyX509TrustManager()};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);HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();httpUrlConn.setSSLSocketFactory(ssf);httpUrlConn.setDoOutput(true);httpUrlConn.setDoInput(true);httpUrlConn.setUseCaches(false);// 设置请求方式(GET/POST)httpUrlConn.setRequestMethod(requestMethod);if ("GET".equalsIgnoreCase(requestMethod)) {httpUrlConn.connect();}// 当有数据需要提交时if (null != outputStr) {OutputStream outputStream = httpUrlConn.getOutputStream();// 注意编码格式,防止中文乱码outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串InputStream inputStream = httpUrlConn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}bufferedReader.close();inputStreamReader.close();// 释放资源inputStream.close();inputStream = null;httpUrlConn.disconnect();} catch (Exception e) {e.printStackTrace();}return buffer.toString();}
}
第三步
用户开始请求登录,appid,redirect_uri都记得改,如果有参数记得携带上(修改state)
https://open.weixin.qq.com/connect/oauth2/authorize?appid=自己的APPID&redirect_uri=http://xbgtgs.natappfree.cc/o2o/wechatlogin/logincheck&role_type=1&response_type=code&scope=snsapi_userinfo&state=参数#wechat_redirect
@Controller
@RequestMapping("wechatlogin")
@Slf4j
public class WechatLoginController {@AutowiredWechatAuthService wechatAuthService;@Autowiredprivate ShopService shopService;private static final Integer FRONTEND = 1;private static final Integer SHOPEND = 2;@GetMapping("/logincheck")public String doGet(HttpServletRequest request, HttpServletResponse response) {// 获取微信公众号传输过来的code,通过code可获取access_token,进而获取用户信息String code = request.getParameter("code");// 这个state可以用来传我们自定义的信息,方便程序调用,这里也可以不用String roleType = request.getParameter("state");WechatUser user = null;String openId = null;if (null != code) {UserAccessToken token;try {// 通过code获取access_tokentoken = WechatUtil.getUserAccessToken(code);// 通过token获取accessTokenString accessToken = token.getAccessToken();// 通过token获取openIdopenId = token.getOpenId();// 通过access_token和openId获取用户昵称等信息user = WechatUtil.getUserInfo(accessToken, openId);} catch (IOException e) {e.printStackTrace();}}return null;}
}
至此我们就获取到了微信用户信息,接下来去数据库查询相关信息,该登录的登录,注册的注册,存储的存储,进行逻辑编写。
微信公众测试号授权登录 学习笔记相关推荐
- 【SpringBoot学习】46、SpringBoot 集成 Uniapp 实现微信公众号授权登录
文章目录 一.公众号环境搭建 二.Spring Boot 集成微信公众号 1.application.yml 微信配置 2.控制层接口 三.Uniapp 实现授权登录 一.公众号环境搭建 本篇文章使用 ...
- 微信公众号授权登录(asp.net + angular)
微信是时下最火的,上面有数以亿计的用户,如果能接入微信将大大减低注册门槛,当然,接入微信登录是有门槛的.微信登录一般有两个,一个是微信开放平台授权登录,一个是微信公众号授权登录,两者都需要认证才可以继 ...
- 基于Spring Boo微信公众号授权登录获取用户信息(附带完整源码)
简介 微信公众号开发中,必不少可少的一环:公众号授权登录.获取微信用户信息. 本地完整运行环境准备 内网渗透=>生成本地指定端口映射的外网域名 传送门:内网渗透工具Natapp使用详解 域名生成 ...
- vue移动端项目微信公众号授权登录
前言 在我们做移动端项目时, 很多功能是以登录后才能进行后续的操作, 并且许多pc端的网页都有微信扫码登录功能, 为了做到pc与移动端统一, 往往移动端项目需要添加微信登录功能, 那么为什么手机端不能 ...
- Java在Web端微信公众号授权登录
Java在Web端微信公众号授权登录 1.需要在微信开发平台配置 url:是自己服务中的微信需要推给你的地址(需要使用二级域名,可以去添加链接描述)购买9块钱1个月使用权或者白嫖都可 token 这个 ...
- H5 微信公众号 授权登录 前后端分离篇(资料准备+前端01)
实现微信公众号授权登录,很简单,但是注意的地方要细心,小伙伴们跟着我的思路一起实现吧! 文章目录 一.帐号申请 1. 正式账号 2. 测试帐号 二.微信文档 2.1. 文档主页 2.2. 授权流程 2 ...
- uni-app 对FastAdmin微信公众号授权登录实例
uni-app 对FastAdmin微信公众号授权登录实例 uniapp 微信公众号授权登录代码 跳转获取code 提交fastadmin 第三方登录插件 进行登录验证 存储token onLoad( ...
- RuoYi-App移动版(uni-app)微信公众号授权登录
前言 略 uni-app 未提供微信公众号授权登录 uni.login是一个客户端API,统一封装了各个平台的各种常见的登录方式,包括App手机号一键登陆.三方登录(微信.微博.QQ.Apple.go ...
- Spring boot 项目(十三)——实现微信公众号授权登录获取用户信息
引言 微信公众号开发中,必不可少的一环:公众号授权登录.获取微信用户信息 前期准备 内网渗透=>生成本地指定端口映射的外网域名 链接:内网渗透工具natapp使用详解 域名生成之后修改yml文件 ...
- uniapp微信公众号授权登录,本地调试
在项目如何集中微信公众号授权登录 后端跳转获取code码,最后拼接, //保留登录前的页面参数.为了不让参数传到后台,并且在微信授权链接带来带去,可以将参数和登录前的地址存到本地缓存let route ...
最新文章
- Linux系统主要目录及作用
- Hyper-V 2节点集群高可用的限制
- bootstrap -- css -- 表格
- 三层架构:软件设计架构
- redis设置开机自启动
- sonar 集群环境工作机制的深入理解
- Hadoop入门(九)Mapreduce高级shuffle之Combiner
- 仿ISQL功能的实现,可以实现批处理功能
- dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单
- 三星宣布华大九天成为其晶圆代工生态系统SAFE EDA合作伙伴
- oracle+执行变量语句,ORACLE sql 语句的执行过程(SQL性能调整)
- 【STM32 .Net MF开发板学习-03】TinyGUI绘图示例
- 实验三lr1分析法java_第十讲 频域分析法(Nyquist曲线)
- Rust: 如何生成一个水仙花数?
- Kafka从上手到实践 - 实践真知:搭建Kafka相关的UI工具 | 凌云时刻
- NoSQLBooster4MongoDB - 用SQL查询MongoDB
- 国网项目汇总(ECP)
- 开源GPU显存虚拟化项目,你的2080Ti还能救一下
- copy-to-clipboard 的拷贝使用
- cad解除块的快捷命令_CAD怎么使用快捷命令快速创建永久块?
热门文章
- Mysql 创建数据库\添加用户\用户授权
- 2021TIOBE 11月榜单:Python蝉联榜首,PHP前十“岌岌可危”
- java同步数据,int类型清空为0
- 移动互联网创业组织可持续发展模型
- 石家庄规划建设智慧城市 三年后城市将大变样
- linux的ip是什么,Linux-IP地址后边加个/8(16,24,32)是什么意思?
- Filter过滤器的作用
- ACL---毕业论文-2
- 动态规划(dynamic programming)初步入门
- 泛微OA流程中调用SAP接口