微信开放平台开发第三方授权登陆(二):PC网页端

article/2025/11/1 12:46:40

微信开放平台开发系列文章:

微信开放平台开发第三方授权登陆(一):开发前期准备

微信开放平台开发第三方授权登陆(二):PC网页端

微信开放平台开发第三方授权登陆(三):Android客户端

微信开放平台开发第三方授权登陆(四):微信公众号

微信开放平台开发第三方授权登陆(五):微信小程序

 

目录

一、需求

二、开发流程

1.网站应用:(微信客户端扫码授权登陆)

三、开发使用的技术及工具

四、具体实现步骤

1、网站应用

1)请求获取Code

2)用户同意授权与否

3)获取access_token

4)通过access_token调用接口获取用户个人信息(UnionID机制)

5)刷新access_token

五、测试结果

1、网站应用

六、应用关键参数位置


微信开放平台第三方授权登陆开发文档(PC网页端)

  当微信开放平台开发第三方授权登陆(一):开发前期准备完成后,已经获取到应用的AppID和AppSecret、且已经成功申请到微信登陆功能。可以进行第三方登陆授权开发。

网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。

一、需求

根据需求,需要拥有第三方微信登录功能,并获取到用户信息。

二、开发流程

1.网站应用:(微信客户端扫码授权登陆)

1)第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

2)通过code参数加上AppID和AppSecret等,通过API换取access_token;

3)通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

网站应用第三方授权登陆获取用户信息

三、开发使用的技术及工具

1、使用IDEA2017.2进行开发

2、使用SpringBoot进行快速开发

3、使用redis进行缓存。

4、使用fastJson对json数据进行处理

5、使用Maven对项目进行管理

四、具体实现步骤

1、网站应用

创建工程

打开IDEA,新建一个工程,选择Spring Initializr,Next。然后填写工程基本信息

选择SpringBoot的版本已经需要添加的依赖,也可以直接跳过,手动添加依赖。由于是web工程,需要添加web相关依赖。模板引擎采用springboot推荐的thymeleaf。最后点击确认,进入工程。

 

添加相关依赖

   <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.5</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.4</version></dependency><!-- 添加httpclient支持 --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.1</version><type>jar</type></dependency>

添加配置文件

SpringBoot默认会将resources下的application名字开头的properties作为配置文件。所以只需要添加application.properties就可以了

由于是使用thymeleaf作为模板引擎。可以添加相应的配置:

#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

为了让系统更具有通用性,分别创建application-dev.properties、application-prod.properties对不同的环境进行配置。

在application.properties中,使用spring.profiles.active进行配置环境的选择。

如:spring.profiles.active = prod

 

如:application-prod.properties

## 微信开放平台
# APPID
wechat.open.appid =
# APPSECRET
wechat.open.appsecret =
# 回调地址
wechat.open.redirect_uri =

新建javaBean:WeChatUserInfo.java

@Getter @Setter @ToString
public class WeChatUserInfo {String openid;String nickname;Integer sex;String province;String city;String country;String headimgurl;String privilege;String unionid;}

新建WeChatOpenLoginController.java实现微信开放平台第三方登录的主要逻辑。

根据文档进行编写代码。

 

1)请求获取Code

前提:应用已经获取相应的网页授权作用域(scope=snsapi_login)

开发:第三方网站引导用户打开链接

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

参数说明:

参数

必须

说明

appid

应用唯一标识

redirect_uri

请使用urlEncode对链接进行处理

response_type

填code

scope

应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可

state

用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

 

注意:若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。


  

  @RequestMapping("/login")public String openWeChatLogin(HttpServletRequest httpServletRequest) {// 防止csrf攻击(跨站请求伪造攻击)String state = UUID.randomUUID().toString().replaceAll("-", "");// 采用redis等进行缓存state 使用sessionId为key 30分钟后过期,可配置RedisPoolUtil.setEx("wechat-open-state-" + httpServletRequest.getSession().getId(), state, Integer.parseInt(env.getProperty("wechat.open.exTime", "1800")));String url = "https://open.weixin.qq.com/connect/qrconnect?" +"appid=" +env.getProperty("wechat.open.pc.appid").trim() +"&redirect_uri=" +env.getProperty("application.url") +env.getProperty("wechat.open.pc.redirect_uri").trim() +"&response_type=code" +"&scope=snsapi_login" +"&state=" +state +     // 由后台自动生成"#wechat_redirect";return "redirect:" + url;}

2)用户同意授权与否

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数

redirect_uri?code=CODE&state=STATE

若用户禁止授权,则不会重定向到我们提供的回调地址中

 

成功授权后,将获得Code,通过Code可以获取access_token

 

3)获取access_token

通过上述方法获取的code获取access_token.

Http Get请求

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

参数说明:

参数

是否必须

说明

appid

应用唯一标识,在微信开放平台提交应用审核通过后获得

secret

应用密钥AppSecret,在微信开放平台提交应用审核通过后获得

code

填写获取的code参数

grant_type

填authorization_code

 

请求后,

返回成功的json串为(样例):

{
"access_token":"ACCESS_TOKEN",        // 接口调用凭证
"expires_in":7200,                      // access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN",       //用户刷新access_token
"openid":"OPENID",                                  //授权用户唯一标识
"scope":"SCOPE",                                     //用户授权的作用域,使用逗号(,)分隔
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"  //当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段
}

失败返回的样例:

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

失败可能原因:  暂时不明

    @RequestMapping("/callback/pc")public String openWeChatCallback(HttpServletRequest httpServletRequest, Model model) {String code = httpServletRequest.getParameter("code");String state = httpServletRequest.getParameter("state");String url = null;// 判断state是否合法String stateStr = RedisPoolUtil.get("wechat-open-state-" + httpServletRequest.getSession().getId());if (StringUtils.isEmpty(code) || StringUtils.isEmpty(stateStr) || !state.equals(stateStr)) {throw new WechatParamException("非法参数,请重新登陆", "/");}url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +"appid=" +env.getProperty("wechat.open.pc.appid").trim() +"&secret=" +env.getProperty("wechat.open.pc.appsecret").trim() +"&code=" +code +"&grant_type=authorization_code";JSONObject wechatAccessToken = HttpClientUtils.httpGet(url);if (wechatAccessToken.get("errcode") != null) {throw new WechatParamException("获取accessToken失败", "/wechat/open/login");}String accessToken = (String) wechatAccessToken.get("access_token");String openid = (String) wechatAccessToken.get("openid");String unionid = (String) wechatAccessToken.get("unionid");if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openid) || StringUtils.isEmpty(unionid)) {throw new WechatParamException("获取accessToken失败", "/wechat/open/login");}// TODO:根据Openid或Unionid对数据库进行查询,如果查询到对应的用户数据,则不需要再向微信服务器发送请求去返回数据。// TODO: 建议使用Unionid作为查询条件。WeChatUserInfo weChatUserInfo = null;wechatAccessToken = null;  // FIXME: 这里应该是从数据库中查询获取用户信息逻辑。if (wechatAccessToken == null) {// 新用户weChatUserInfo = getUserInfoByAccessToken(accessToken);// 数据库插入的操作}if (weChatUserInfo != null) {model.addAttribute(weChatUserInfo);return "wechatUser";}throw new WechatParamException("获取用户信息失败", "/wechat/open/login");}

4)通过access_token调用接口获取用户个人信息(UnionID机制)

前提:

1. access_token有效且未超时;

2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

Http Get请求:

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

参数

是否必须

说明

access_token

调用凭证

openid

普通用户的标识,对当前开发者帐号唯一

lang

国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

 

返回成功的json结果(样例):

{
"openid":"OPENID",        //普通用户的标识,对当前开发者帐号唯一
"nickname":"NICKNAME",   //普通用户昵称
"sex":1,                                //普通用户性别,1为男性,2为女性
"province":"PROVINCE",      //普通用户个人资料填写的省份
"city":"CITY",                        //普通用户个人资料填写的城市
"country":"COUNTRY",         //国家,如中国为CN
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",       //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
"privilege":[   //用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"   //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的
}

 

失败JSON样例:

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

 

注意:在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况

最好保存用户unionID信息,以便以后在不同应用中进行用户信息互通。

private WeChatUserInfo getUserInfoByAccessToken(String accessToken) {if (StringUtils.isEmpty(accessToken)) {return null;  //"accessToken为空";}String get_userInfo_url = null;get_userInfo_url = "https://api.weixin.qq.com/sns/userinfo?" +"access_token=" +accessToken +"&openid=" +env.getProperty("wechat.open.pc.appid").trim();String userInfo_result = HttpClientUtils.httpGet(get_userInfo_url, "utf-8");if (!userInfo_result.equals("errcode")) {WeChatUserInfo weChatUserInfo = JSON.parseObject(userInfo_result, new TypeReference<WeChatUserInfo>() {});// TODO: 需要把头像信息下载到文件服务器,然后替换掉头像URL。微信的或许不可靠,假设微信用户更换了头像,旧头像URL是否会保存?而这个URL信息却存放在我们的数据库中,不可靠return weChatUserInfo;}return null;  //"获取用户信息失败"}

5)刷新access_token

由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

 

请求方法:

获取第一步的code后,请求以下链接进行refresh_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参数

 

成功返回的结果:

{
"access_token":"ACCESS_TOKEN",    //接口调用凭证
"expires_in":7200,                             // access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN",   //用户刷新access_token
"openid":"OPENID",                          //授权用户唯一标识
"scope":"SCOPE"                              //用户授权的作用域,使用逗号(,)分隔
}

失败样例:

{"errcode":40030,"errmsg":"invalid refresh_token"}

 

注意:

1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。

 

五、测试结果

1、网站应用

首先开启redis。然后运行代码。由于SpringBoot会使用内置的Tomcat容器进行管理,直接运行就可以了,然后点击微信登录。弹出扫码登录窗口,手机扫码同意登录后就可以获取到用户信息了.

 

六、应用关键参数位置

APPID和APPSecret以及回调地址位置,注:需要修改授权回调域,即回调地址

 


http://chatgpt.dhexx.cn/article/651wDSe1.shtml

相关文章

.md文件用什么软件打开

记事本-------体验感差 效果&#xff1a; Notepad 毫无疑问的完胜记事本 官网下载地址&#xff1a;https://notepad-plus.en.softonic.com/download &#xff08;下载速度比较慢&#xff09; 这是百度网盘&#xff1a;&#xff08;会快一点点&#xff09; 链接&#xff1a;ht…

md文件打开方式推荐

MD文件介绍 以下介绍来自于百度&#xff1a; md文件是Markdown语法编写的文件&#xff0c;Markdown是一款轻量级的标记语言&#xff0c;可以使用语法来代替排版&#xff0c;插入公式和图片等都非常的容易&#xff0c;目前很多博客都可以使用该语法去编辑。使用Markdown的好处…

md文件如何打开?

阅读md文件时 常常会手足无措 今天教大家如何打开md文件 当在阅览md文件时&#xff0c;一般系统默认是记事本&#xff1a; 阅览效果极其不佳且编辑体验极差&#xff01; 今天推荐一款软件&#xff1a;Typora 直接上链接&#xff1a;下载地址&#xff08;官网&#xff09; …

Windows下右键新建.md文件教程(转)

Windows下右键新建.md文件教程 转载自Keavnn’Blog&#xff0c;并有些许修正 原本创建.md文件需要首先打开markdown文本编辑器&#xff0c;如Typora&#xff0c;或者新建.txt文件然后修改后缀名&#xff0c;本文介绍了如何在Windows操作系统中添加右键创建.md文件的方法。 环…

md文件使用

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

如何编写md格式的文档、vscode中写.md文件的插件推荐

目录 1. 标题 2. 字体 3. 引用 4. 分割线 5. 图片 6. 超链接 7. 无序列表 8. 有序列表 9. 列表嵌套 10. 表格 11.代码 12. vscode中写.md文件的插件推荐 .md格式的文章可以用编辑器Markdown打开&#xff0c;Markdown是一种纯文本格式的标记语言。通过简单的标记语法…

md文件转换成word文档

md文件转成word文档 Typora导出word文件时需要先下载pandoc Typora导出word文件时因为文档里面有表格&#xff0c;导出失败&#xff0c;所以先使用使用pandoc命令导出无边框表格的word 1.在xxx.md所在文件夹打开命令提示符 2.在命令提示符输入&#xff1a;pandoc -s xxxx.md …

.md文件以及markdown语法书写md文档

.md文件以及markdown语法书写md文档 1. .md文件如何打开2. markdown是什么&#xff1f;2.1 markdown用来干嘛&#xff1f;2.2 怎样书写和读取markdown&#xff1f; 3. markdown语法3.1 基本符号3.2 标题&#xff08;从大到小取决于#号的数量&#xff09;3.3 正文3.4 段落3.5 字…

md文档的阅读查看

前言&#xff1a; md文档可以用vscode看&#xff0c;也可以直接拖入浏览器看&#xff0c;但看起来不太好看&#xff0c;效果如下&#xff1a; 改进方法&#xff1a; 方法1、假如你的电脑安装了node.js &#xff08;1&#xff09;判断是否安装&#xff1a;WindowsR&#xff0…

如何将md文件完美转化为 PDF?

今天在网上搜kali相关教程时&#xff0c;无意中找到一本很好的教程&#xff0c;但是它是以*.md的文件形式放在github上&#xff0c;我试了将原文件zip下载到本地&#xff0c;但怎么能将.md文件转成PDF文件呢&#xff1f;&#xff08;如果你用Visual Studio code, 那么安装Markd…

如何编写.md格式文件?

文章目录 如何编写.md格式文件&#xff1f;1.标题2.字体3.插入图片操作4.不带快捷键Markdown书写操作5.Markdown拓展功能6.主题替换 如何编写.md格式文件&#xff1f; md即markdown&#xff0c;百度的解释&#xff1a;Markdown是一种可以使用普通文本编辑器编写的标记语言&…

加载.md文件

webpack是不能直接加载.md文件的&#xff0c;但是一些博客或者文章指导类的内容通过markdown进行编辑管理是比较常见的&#xff0c;这就需要我们进行一些配置&#xff0c;使webpack能够加载.md文件&#xff0c;并将文件内容展示到网页上。 1、先写一个md加载器 在这之前&…

.md文件的打开

今天终于知道.md文件是markdown格式的了&#xff0c; windows下可以安装markdownpad来打开md文件&#xff1a; http://blog.csdn.net/github_35160620/article/details/52158604 ubuntu下则可安装retext&#xff0c;查看时 retext xxx.md即可 例子&#xff1a; ubuntu下&…

pdf文件转为md文件

针对Windows 方法一&#x1f4a1; 下载Pandoc 由于Pandoc不支持PDF直接转为md形式&#xff0c;先将PDF文档转换为Word形式&#xff0c;再使用Typora将你的Word文件导入。 途径 1 &#xff1a; \textcolor{green}{途径1&#xff1a;} 途径1&#xff1a;&#x1f528; 官网下载…

md文件的相关使用

天已雪&#xff0c;一杯否&#xff1f; —— 南风落尽 前言 因为天冷&#xff0c;已经很久没有更新博客了&#xff0c;想了想&#xff0c;还是决定写一篇水文&#xff0c;一是促使自己记得写文章&#xff0c;二是记录自己平时学到的杂七杂八的东西&#xff0c;免得忘了又到处…

md是什么类型的文件?怎么打开md文件,Markdown的编写,Markdown转化为html

md 就是 Markdown 的文件&#xff0c;Markdown 是一种轻量级标记语言。CSDN 的博客就是用 markdown 来编写的呢&#xff01;html 大家不陌生吧&#xff0c;他是超文本标记语言&#xff0c;他们都是标记语言&#xff0c;那有什么区别呢&#xff1f; html 要比 Markdown 复杂很多…

md文件用什么打开

如果想要阅读本地的.md文件&#xff0c;又懒得下markdown笔记软件或者电脑上内存紧张的话&#xff0c;一个好方法就是在电脑浏览器里面添加相关的markdown阅读插件&#xff0c;以Win10自带的Edge浏览器为例&#xff1a; Chrome浏览器类似 Microsoft Edge AddonsMake Microsoft …

win10打开.md文件

工具/原料 DELL 台式机 Windows 10 Microsoft Edge103.0.1264.49 方法/步骤 1 从网络上下载一些技术文档&#xff0c;有些通常是以md后缀格式提供的&#xff0c;这是一种MarkDown语言格式的文档&#xff0c;有时下载MarDown编辑器仍然会无法正常显示&#xff0c;如下图所示&…

如何将.md文件转换为pdf

目录 1.step1&#xff1a; 安装Visual Studio Code&#xff08;简称VScode&#xff09; 2.step2&#xff1a; 安装定制化插件 3.step3&#xff1a; 进入预览窗口模式 4.step4&#xff1a; 进行格式转换 1.step1&#xff1a; 安装Visual Studio Code&#xff08;简称VScode&a…

.md文件转.pdf文件

一、安装VS code vscode是一个轻量级的、可扩展性十分强的开发编辑器。过程略&#xff0c;比较简单。 二、安装插件Markdown PDF 直接 install 就可以了。 我这里出现了安装失败的情景&#xff0c;这时候可以通过它给的提示&#xff0c;安转markdown-pdf 的 .vsix 文件&#…