微信-验证服务器有效性
微信-网页授权获取用户信息

网页授权获取用户信息步骤

第一步:用户同意授权,获取code
第二步:通过code换取网页授权access_token
第三步:拉取用户信息(需scope为 snsapi_userinfo)

第一步:用户同意授权,获取code

要填写网页授权回调域名:

1.在网页帐号处点击”修改”按钮

2.填写域名(注意不要http://, 不要后面的路由)

在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导用户打开如下页面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。

参数说明

参数 是否必须 说明
appid 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
response_type 返回类型,请填写code
scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数

如果用户点击同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。

若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE

code说明 :

code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

第二步:通过code换取网页授权access_token

首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。

公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

获取code后,GET请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

GET参数说明

参数 是否必须 说明
appid 公众号的唯一标识
secret 公众号的appsecret
code 填写第一步获取的code参数
grant_type 填写为authorization_code

正确时返回的JSON数据包如下:

{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE","unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔
unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。

错误时微信会返回JSON数据包如下(示例为Code无效错误):

{"errcode":40029,"errmsg":"invalid code"}

第三步:拉取用户信息(需scope为 snsapi_userinfo)

如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。

请求方法

http:GET(请使用https协议)

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参数说明

参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
openid 用户的唯一标识
lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

返回说明

正确时返回的JSON数据包如下:

{"openid":" OPENID"," nickname": NICKNAME,"sex":"1","province":"PROVINCE""city":"CITY","country":"COUNTRY","headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", "privilege":["PRIVILEGE1""PRIVILEGE2"],"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 描述
openid 用户的唯一标识
nickname 用户昵称
sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
province 用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。

错误时微信会返回JSON数据包如下(示例为openid无效):

{"errcode":40003,"errmsg":" invalid openid "}

终于上代码了:

HttpsUtil.java

package com.jeiker.demo.util;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.URL;public class HttpsUtil {/*** 以https方式发送请求并将请求响应内容以String方式返回** @param path   请求路径* @param method 请求方法* @param body   请求数据体* @return 请求响应内容转换成字符串信息*/public static String httpsRequestToString(String path, String method, String body) {if (path == null || method == null) {return null;}String response = null;InputStream inputStream = null;InputStreamReader inputStreamReader = null;BufferedReader bufferedReader = null;HttpsURLConnection conn = null;try {// 创建SSLConrext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = {new JEEWeiXinX509TrustManager()};SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述对象中的到SSLSocketFactorySSLSocketFactory ssf = sslContext.getSocketFactory();System.out.println(path);URL url = new URL(path);conn = (HttpsURLConnection) url.openConnection();conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);//设置请求方式(git|post)conn.setRequestMethod(method);//有数据提交时if (null != body) {OutputStream outputStream = conn.getOutputStream();outputStream.write(body.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串inputStream = conn.getInputStream();inputStreamReader = new InputStreamReader(inputStream, "UTF-8");bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}response = buffer.toString();} catch (Exception e) {} finally {if (conn != null) {conn.disconnect();}try {bufferedReader.close();inputStreamReader.close();inputStream.close();} catch (IOException execption) {}}return response;}
}

JEEWeiXinX509TrustManager.java

package com.jeiker.demo.util;import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;class JEEWeiXinX509TrustManager 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;}
}

UserInfoUtil.java

package com.jeiker.demo.util;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class UserInfoUtil {private Logger logger = LoggerFactory.getLogger(getClass());// 1.获取code的请求地址public static String Get_Code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect";// 替换字符串public static String getCode(String APPID, String REDIRECT_URI,String SCOPE) {return String.format(Get_Code,APPID,REDIRECT_URI,SCOPE);}// 2.获取Web_access_tokenhttps的请求地址public static String Web_access_tokenhttps = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";// 替换字符串public static String getWebAccess(String APPID, String SECRET,String CODE) {return String.format(Web_access_tokenhttps, APPID, SECRET,CODE);}// 3.拉取用户信息的请求地址public static String User_Message = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";// 替换字符串public static String getUserMessage(String access_token, String openid) {return String.format(User_Message, access_token,openid);}public static void main(String[] args) {String REDIRECT_URI = "http://wechat.tmqyt.com/url";String SCOPE = "snsapi_login"; // snsapi_userinfo // snsapi_login//appIdString appId = "wx222e322a20897ea3";String getCodeUrl = getCode(appId, REDIRECT_URI, SCOPE);System.out.println("getCodeUrl:"+getCodeUrl);}
}

RedirectController.java


package com.jeiker.demo.controller;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.jeiker.demo.util.HttpsUtil;
import com.jeiker.demo.util.UserInfoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RedirectController {private Logger logger = LoggerFactory.getLogger(getClass());public static final String WX_APPID = "wx222e322a20897ea3";public static final String WX_APPSECRET = "c9d547819234dd0059bf4b23422409e1";/*** 微信网页授权流程:* 1. 用户同意授权,获取 code* 2. 通过 code 换取网页授权 access_token* 3. 使用获取到的 access_token 和 openid 拉取用户信息* @param code  用户同意授权后,获取到的code* @param state 重定向状态参数* @return*/@GetMapping("/url")public String wecahtLogin(@RequestParam(name = "code", required = false) String code,@RequestParam(name = "state") String state) {// 1. 用户同意授权,获取codelogger.info("收到微信重定向跳转.");logger.info("用户同意授权,获取code:{} , state:{}", code, state);// 2. 通过code换取网页授权access_tokenif (code != null || !(code.equals(""))) {String APPID = WX_APPID;String SECRET = WX_APPSECRET;String CODE = code;String WebAccessToken = "";String openId = "";String nickName,sex,openid = "";String REDIRECT_URI = "http://www.xxx.com/url";String SCOPE = "snsapi_userinfo";String getCodeUrl = UserInfoUtil.getCode(APPID, REDIRECT_URI, SCOPE);logger.info("第一步:用户授权, get Code URL:{}", getCodeUrl);// 替换字符串,获得请求access token URLString tokenUrl = UserInfoUtil.getWebAccess(APPID, SECRET, CODE);logger.info("第二步:get Access Token URL:{}", tokenUrl);// 通过https方式请求获得web_access_tokenString response = HttpsUtil.httpsRequestToString(tokenUrl, "GET", null);JSONObject jsonObject = JSON.parseObject(response);logger.info("请求到的Access Token:{}", jsonObject.toJSONString());//            {
//                "access_token":"ACCESS_TOKEN",
//                "expires_in":7200,
//                "refresh_token":"REFRESH_TOKEN",
//                "openid":"OPENID",
//                "scope":"SCOPE",
//                "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
//            }if (null != jsonObject) {try {WebAccessToken = jsonObject.getString("access_token");openId = jsonObject.getString("openid");logger.info("获取access_token成功!");logger.info("WebAccessToken:{} , openId:{}", WebAccessToken, openId);// 3. 使用获取到的 Access_token 和 openid 拉取用户信息String userMessageUrl = UserInfoUtil.getUserMessage(WebAccessToken, openId);logger.info("第三步:获取用户信息的URL:{}", userMessageUrl);// 通过https方式请求获得用户信息响应String userMessageResponse = HttpsUtil.httpsRequestToString(userMessageUrl, "GET", null);JSONObject userMessageJsonObject = JSON.parseObject(userMessageResponse);logger.info("用户信息:{}", userMessageJsonObject.toJSONString());
//                    {
//                        "openid":" OPENID",
//                        "nickname": NICKNAME,
//                        "sex":"1",
//                        "province":"PROVINCE"
//                        "city":"CITY",
//                        "country":"COUNTRY",
//                        "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MoCfHe/46",
//                        "privilege":[
//                              "PRIVILEGE1"
//                              "PRIVILEGE2"
//                        ],
//                        "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
//                    }if (userMessageJsonObject != null) {try {//用户昵称nickName = userMessageJsonObject.getString("nickname");//用户性别sex = userMessageJsonObject.getString("sex");sex = (sex.equals("1")) ? "男" : "女";//用户唯一标识openid = userMessageJsonObject.getString("openid");logger.info("用户昵称:{}", nickName);logger.info("用户性别:{}", sex);logger.info("OpenId:{}", openid);} catch (JSONException e) {logger.error("获取用户信息失败");}}} catch (JSONException e) {logger.error("获取Web Access Token失败");}}}return "登录成功";}
}

服务器日志:

: 收到微信重定向跳转.
: 用户同意授权,获取code:021qx2lsdf1FuDi90DX2l90qx2le , state:STAT
: getCodeUrl:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx222e333a20897ea3&redirect_uri=http://www.xxx.com/url&response_type=code&scope=snsapi_userinfo&state=STAT#wechat_redirect
: get Access Token URL:https://api.weixin.qq.com/sns/oauth2/access_token?appid= wx222e333a20897ea3&secret=c9d547819089dd0059bf4b234234209e1&code=021qx2l90VHASD23SADDi90DX2l90qx2le&grant_type=authorization_code
https://api.weixin.qq.com/sns/oauth2/access_token?appid= wx222e333a20897ea3&secret=c9d5478190ASDFAQWEb39691409e1&code=021qx2l90VHWPt1FuDi9WEQQWE0qx2le&grant_type=authorization_code
: 请求到的Access Token:{"access_token":"64CDRyZVwASDADSADSF2WCtel0VSUzrD4fswL2cqy0yNcNXAc1NXBi-KgGD6RLARf3SSnzZyXl-dAe2-xIfRnCY3m23uRWLxj-uGWkxZI","refresh_token":"iaTZN1ASDFASDFApCAINItDYMYDKwjwZo9XwYfNyIUZadAasXyJCHsvAUc1A8KakXPiASDFSADFmebcAuqP6Zn4G5N7Vjls0Nssd2R_XqE","openid":"ojUgjt6tkI08QASDFASZLKgsVR24","scope":"snsapi_userinfo","expires_in":7200}
: 获取access_token成功!
: WebAccessToken:64CDRyZVwASDFASDFACtel0VSUzrD4fswL2cqy0yNcNXAc1NXBi-KgGD6RLARf3SSnzZyXl-dAe2-xIfRnCY3m23uRWLxj-uGWkxZI , openId:ojUgjt6tkI08QzSfqgzZLKgsVR24
: 获取用户信息的URL:https://api.weixin.qq.com/sns/userinfo?access_token=64CDRyZVwc7fwASDFASDFASDFASDFASDFASDcqy0yNcNXAc1NXBi-KgGD6RLARf3SSnzZyXl-dAe2-xIfRnCY3m23uRWLxj-uGWkxZI&openid=ojUgjt6tASDFASDFASDFSADFzZLKgsVR24&lang=zh_CN
https://api.weixin.qq.com/sns/userinfo?access_token=64CDRyZVwc7fwyLclOASDFASDFASDFSADFcqy0yNcNXAc1NXBi-KgGD6RLARf3SSnzZyXl-dAe2-xIfRnCY3m23uRWLxj-uGWkxZI&openid=ojUgjt6tkI08QzSfqgzZLKgsVR24&lang=zh_CN
: 用户信息:{"country":"中国","province":"广东","city":"深圳","openid":"ojUgjt6ASDFASDFASDgzZLKgsVR24","sex":1,"nickname":"xiao","headimgurl":"http://wx.qlogo.cn/mmopen/llaPdPm9YKCcASDFASDFASDFWt5vVYbWWIwnhW2BJOJV8QEsem9OhP3gCLJWYUrGOPK232JEMof3THVVlH/0","language":"zh_CN","privilege":[]}
: 用户昵称:xiao
: 用户性别:男
: OpenId:ojUgjt6tkI08QzSfASDFgasdagsVR24

刷新access_token(如果需要)

由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。

请求方法

获取第二步的refresh_token后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数 是否必须 说明
appid 公众号的唯一标识
grant_type 填写为refresh_token
refresh_token 填写通过access_token获取到的refresh_token参数

正确时返回的JSON数据包如下:

{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"
}
参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔

错误时微信会返回JSON数据包如下(示例为Code无效错误):

{"errcode":40029,"errmsg":"invalid code"}

Spring Boot 微信-网页授权获取用户信息相关推荐

  1. PHP 微信网页授权获取用户信息

    最近用到过微信用户授权获取用户信息的功能,在这里记录一下. 因为用户授权要用到认证过的服务号才有权限,而线上正在使用公众号,而开发就有些不方便了,这里可以申请一个微信公众测试号. 1.申请一个微信公众 ...

  2. 微信网页授权获取用户信息实战代码

    微信授权的整体思路: 1 第一步:用户同意授权,获取code 2 第二步:通过code换取网页授权access_token 3 第三步:刷新access_token(如果需要) 4 第四步:拉取用户信 ...

  3. 微信用户绑定java实例_OAuth2.0微信网页授权获取用户信息实现全过程(JAVA版本)...

    一.前言 为什么需要OAuth2.0网页授权接口,主要是为了获取微信用户的基本信息(比如用户绑定,用户统计等等) 特别注意:只有认证的服务号有此接口权限 那么订阅号如何实现这个功能呢?可以通过另一个服 ...

  4. laravel-admin微信网页授权获取用户信息过程

    最近在重构我们平台得前端页面以及逻辑,再此记录一下微信网页版授权获取用户资料得过程 第一步,安装 composer require "overtrue/laravel-wechat:~3.0 ...

  5. 连小白都能看懂的微信开发之 微信自定义菜单 + 获取网页授权 + 获取用户信息

    微信自定义菜单+获取网页授权+获取用户信息 今天项目需要一个需求,就是添加一个菜单接口,并且还可以获取用于的信息,从而根据用户的信息去做一些业务的查询.通过百度和自己查看文档大致的解决办法如下: 注意 ...

  6. 微信网页授权获取用户基本信息 --- 20/03/16

    ThinkPHP5实现微信网页授权获取用户基本信息 本次使用的appID与appSecret为公众号 一:准备工作 登录微信公众平台,左侧菜单下拉至开发选中基本配置 启用开发者密码(AppSecret ...

  7. PHP开发之-微信网页授权获取用户基本信息

    如何通过网页授权获取用户基本信息(国家,省,市,昵称)相关信息 必要条件: 1)公众号认证 2)有网页授权获取用户基本信息的权限接口 注意:最近有朋友说:在公众平台申请的测试号,会出现无法取到用户信息 ...

  8. PHP通过微信网页授权获取用户基本信息

    微信网页授权获取用户基本信息: <?php$appid = '你的appid'; $secret = '你的secret';if (isset($_GET['code'])) {$code = ...

  9. 支付宝 网页授权 获取用户信息

    ****** 支付宝 网页授权 获取用户信息(昵称,头像等)****** 最近有个项目 需要获取到支付宝的头像和昵称作为互动数据,作为php新人,对于看文档来说 很是痛苦,网上也没有很多关于支付宝网页 ...

最新文章

  1. 2017-2018-1 20155202 《信息安全系统设计基础》第9周学习总结
  2. Python使用matplotlib可视化华夫饼图(Waffle Chart) 、华夫饼图可以直观地显示完成度(百分比)或者部分占整体的比例、从不同的分类变量来可视化华夫饼图(Waffle Chart
  3. 【pytorch】拟合sin函数
  4. salt-ssh 安装salt-minion 笔记
  5. android 中使用ExpandableListView控件结合服务器json文件的下载
  6. 找斐波那契数列中的第N个数——递归与函数自调用算法
  7. java runnable 异常_JAVA 线程中的异常捕获
  8. 第九章 隐马尔科夫模型HMM
  9. 对!这就是你要的pandas数据清洗练习题(❤️)
  10. python socket读取数据不能解析_通过实例解析return运行原理,除了quot;生孩子quot;python真是无所不能啊...
  11. idea 注册码 实测可用
  12. 【kafka】kafka 查看 GroupCoordinator
  13. win11系统怎么样 Windows11系统好用吗
  14. Gentle.NET Attribute
  15. ubuntu jdk 安装 【转载】
  16. x9此计算机上没有hasp_中琅条码打印软件安装后弹出HASP错误代码处理方法
  17. 微信小程序如何实现登陆功能
  18. 香农编码Shannon
  19. 服务器winsxs文件夹怎么清理工具,win7如何使用WinSxS工具安全删除WinSxS文件夹垃圾...
  20. HDU - 5894 hannnnah_j’s Biological Test 组合数(插板法)

热门文章

  1. 【转】Java方向如何准备BAT技术面试答案(汇总版)
  2. 微信单删和互删有什么区别?
  3. 机器学习入门 笔记(二) 机器学习基础概念
  4. BeautyGAN图片的高精度美颜
  5. rest_framework学习之解析器(Parsers)
  6. 餐桌 (Standard IO)
  7. 游戏盾是什么/为什么app会被攻击
  8. HIVE优化系列(1)-- 自动合并输出的小文件
  9. 方法入参很复杂,每次调用都要构造BO入参?一招教你自动构造入参
  10. kali linux实体机_kali linux系统安装之物理机的详细安装步骤