开放平台–扫描微信二维码登录

article/2025/9/18 9:00:01

准备

如不了解第三方登录流程,建议先大概了解一下,在来看看代码。
说明: 由于开放平台无测试号测试,所以只能上开放平台进行配置信息。公众平台的测试号并不能给开放平台使用。

微信开放平台地址:https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN

配置步骤如下:

1、创建web应用
在这里插入图片描述
当创建成功的时候会有appidappsecret,下面代码需要用到。
创建好之后需要设置回调域 ,就是当扫码通过之后会调用该域内的地址,地址在下面代码种配置。

2、注意!!!
1、设置回调域的时候,前面不能加上http://等协议。只需要配置域名即可,如baidu.com,spring.io等。填写成http://spring.io/是错误的
2、域名不能加端口号

代码

<一> 获取二维码

  /*** 跳转至微信登录界面*/// Result 定义的类,返回给前端的信息@ApiOperation(value = "网站-微信扫码登录路径", notes = "网站-微信扫码登录路径")@GetMapping(value = "/web/wxLoginPage")public Result webWxKfLoginPage() throws Exception {String url = WeChatLoginUtil.webWxKfLoginPage();return Result.Builder.newBuilder(AppTipStatusEmum.SUCCESS_STATUS.getCode(), AppTipMsgEnum.SELECT_SUCCESS.getText()).setMessage("获取二维码成功!").setData(url).build();}

涉及的WeChatLoginUtil类如下:

import com.uwa.mall.user.module.enums.ThirdPartyLoginEnum;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;public class WeChatLoginUtil {// ===============================================web方式==================================================// 网页方式登录(scope=snsapi_login)public static String webWxKfLoginPage() throws Exception {// 防止csrf攻击(跨站请求伪造攻击)String state = UUID.randomUUID().toString().replaceAll("-", "");// 存入redis。 CacheUtil为封装redis的工具类CacheUtil.set(ThirdPartyLoginEnum.WeChatEnum.WeChatKFState.getCode() + state, "ok", Integer.valueOf(ThirdPartyLoginEnum.WeChatEnum.WeChatKFStateTime.getCode()));// 普通微信三方地址String url = ThirdPartyLoginEnum.WeChatEnum.AppUrl.getCode() + "appid=" + ThirdPartyLoginEnum.WeChatEnum.AppID.getCode() + "&redirect_uri=" + ThirdPartyLoginEnum.WeChatEnum.RedirectUri.getCode()+ "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect";return url;}/*** 通过code获取token** @return*/public static Map getAccessToken(String code, String appid, String secret) throws Exception {// 构建请求数据Map t = new HashMap();t.put("appid", appid);t.put("secret", secret);t.put("code", code);t.put("grant_type", "authorization_code");// 调用httpclient处理请求得到返回json数据String returnJson = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.AccessTokenUri.getCode(), t);Map token = JsonUtil.fromJson(returnJson, Map.class);return token;}/*** 刷新token处理** @return*/public static Map refreshToken(String appid, String refresh_token) throws Exception {// 构建请求参数Map m = new HashMap();m.put("appid", appid);m.put("grant_type", "refresh_token");m.put("refresh_token", refresh_token);String s = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.UrlRefresh.getCode(), m);// 调用httpclient发出请求Map refreshToken = JsonUtil.fromJson(s, Map.class);return refreshToken;}/*** 通过token获取用户信息* * @param token* @return*/public static String getUserInfo(Map token) throws Exception {// 构建请求数据Map u = new HashMap();u.put("access_token", token.get("access_token"));u.put("openid", token.get("openid"));u.put("lang", "zh_CN");// 调用httpclient处理请求得到用户信息json数据String userinfo = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.UrlUserInfo.getCode(), u);return userinfo;}// ===============================================公众号方式==================================================// 公众号方式登录(scope=snsapi_base)public static String publicWxKfLoginPage() {String state = UUID.randomUUID().toString().replaceAll("-", "");CacheUtil.set(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFState.getCode() + state, "ok", Integer.valueOf(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFStateTime.getCode()));String url = ThirdPartyLoginEnum.PublicWeChatEnum.AppUrl.getCode() + "appid=" + ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode() + "&redirect_uri="+ ThirdPartyLoginEnum.PublicWeChatEnum.RedirectUri.getCode() + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect";return url;}// 公众号 通过code获取tokenpublic static Map getAccessTokenByPublic(String code, String appid, String secret) throws Exception {// 构建请求数据Map t = new HashMap();t.put("appid", appid);t.put("secret", secret);t.put("code", code);t.put("grant_type", "authorization_code");// 调用httpclient处理请求得到返回json数据String returnJson = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.AccessTokenUri.getCode(), t);Map token = JsonUtil.fromJson(returnJson, Map.class);return token;}public static Map refreshTokenByPublic(String appid, String refresh_token) throws Exception {// 构建请求参数Map m = new HashMap();m.put("appid", appid);m.put("grant_type", "refresh_token");m.put("refresh_token", refresh_token);String s = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.UrlRefresh.getCode(), m);// 调用httpclient发出请求Map refreshToken = JsonUtil.fromJson(s, Map.class);return refreshToken;}public static String getUserInfoByPublic(Map token) throws Exception {// 构建请求数据Map u = new HashMap();u.put("access_token", token.get("access_token"));u.put("openid", token.get("openid"));u.put("lang", "zh_CN");// 调用httpclient处理请求得到用户信息json数据String userinfo = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.UrlUserInfo.getCode(), u);return userinfo;}}

涉及的ThirdPartyLoginEnum枚举接口类如下:

// 第三方登录方式
public interface ThirdPartyLoginEnum {// 网页微信登录方式enum WeChatEnum {AppID("xxx.....xxx","微信开发平台的AppID"),AppSecret("xxx.....xxx","微信开发平台的AppSecret"),AppUrl("https://open.weixin.qq.com/connect/qrconnect?","微信第三方地址"),RedirectUri("http://www.ycj.com/login/wxLogin","登录成功的回调地址"),  //这里的域名和前面配置的域名必须一致,且不能加端口号AccessTokenUri("https://api.weixin.qq.com/sns/oauth2/access_token","获取access_token的地址"),UrlRefresh("https://api.weixin.qq.com/sns/oauth2/refresh_token","刷新获取微信token"),UrlUserInfo("https://api.weixin.qq.com/sns/userinfo","获取用户信息"),WeChatKFState("wechat-kf-state","redis的key"),WeChatKFStateTime("300","redis的key的过期时间(秒)");private String code;private String msg;WeChatEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}// 公众号微信登录方式(移动端)enum PublicWeChatEnum {AppID("xxx.....xxx","微信公众平台的AppID"),AppSecret("xxx.....xxx","微信公众平台的AppSecret"),AppUrl("https://open.weixin.qq.com/connect/oauth2/authorize?","微信第三方地址"),RedirectUri("http://activate.navicat.com/mall/user/api/loginAndRegister/public/wxLoginCallback","登录成功的回调地址"),  //这里的域名和公众平台(不是本文的)配置的域名必须一致,且不能加端口号AccessTokenUri("https://api.weixin.qq.com/sns/oauth2/access_token","获取access_token的地址"),UrlRefresh("https://api.weixin.qq.com/sns/oauth2/refresh_token","刷新获取微信token"),UrlUserInfo("https://api.weixin.qq.com/sns/userinfo","获取用户信息"),WeChatKFState("wechat-kf2-state","redis的key"),WeChatKFStateTime("300","redis的key的过期时间(秒)");private String code;private String msg;PublicWeChatEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}enum CacheParamEnum{WXOpenID("WX_OpenID_","redis的key"),WXOpenIDTime("300","redis的key的过期时间(秒)");private String code;private String msg;CacheParamEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}}

<二>扫码登录回调

  // type有web和public两种类型,本文是开放平台,{type}使用的是web@ApiOperation(value = "微信登录回调", notes = "微信登录回调")@GetMapping("/{type}/wxLoginCallback")public Result wxLoginCallback(@PathVariable("type") String type, @RequestParam(name = "code") String code, @RequestParam(name = "state", required = false) String state) throws Exception {return thirdLoginService.wxLoginCallback(code, state, type);}

涉及的thirdLoginService.wxLoginCallback接口代码如下:

  // 微信登录回调@Override@Transactional(rollbackFor = Exception.class)public Result wxLoginCallback(String code, String state, String type) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");Map userMap = null;int regType = RegisterTypeEnum.WX_WEB.getCode();  //枚举:web类型是开放平台,public是公众平台if ("web".equals(type)) {userMap = thirdGetUserInfoService.wxGetUserInfo(code, state);  //获取用户信息} else if ("public".equals(type)) {regType = RegisterTypeEnum.WX_MP.getCode();userMap = thirdGetUserInfoService.wxPublicGetUserInfo(code, state);  //获取用户信息} else {AssertException.assertException(AppTipMsgEnum.LOGIN_FAIL.getCode(), "回调类型错误!");}AssertException.isNullObject(userMap, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(userMap.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + userMap.get("errmsg") + ",请重新登录!");AssertException.isNullObject(userMap.get("openid"), AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:openid为空!,请重新登录!");// 以下是你自己的代码逻辑操作......// 以下是你自己的代码逻辑操作......// 以下是你自己的代码逻辑操作......return Result.Builder.newBuilder(AppTipStatusEmum.SUCCESS_STATUS.getCode(), AppTipMsgEnum.SUCCESS.getText()).setData(objectMap).build();}

涉及的thirdGetUserInfoService类的代码如下:

@Service("thirdGetUserInfoService")
public class ThirdGetUserInfoServiceImpl implements ThirdGetUserInfoService {// 微信web方式获取用户信息@Overridepublic Map wxGetUserInfo(String code, String state) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");// 判断state是否合法String stateStr = CacheUtil.get(ThirdPartyLoginEnum.WeChatEnum.WeChatKFState.getCode() + state);AssertException.assertException(StringUtils.isEmpty(code) || StringUtils.isEmpty(state) || StringUtils.isBlank(stateStr), AppTipMsgEnum.PARAM_NOT_NULL.getCode(), "非法操作,请重新登录!");// 用户授权后的code换取tokenMap t_token = WeChatLoginUtil.getAccessToken(code, ThirdPartyLoginEnum.WeChatEnum.AppID.getCode(), ThirdPartyLoginEnum.WeChatEnum.AppSecret.getCode());// 判断是否成功获取到了tokenAssertException.isNullObject(t_token, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(t_token.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + t_token.get("errmsg") + ",请重新登录!");AssertException.assertException(StringUtils.isEmpty((String) t_token.get("access_token")) || StringUtils.isEmpty((String) t_token.get("openid")), AppTipMsgEnum.PARAM_NOT_NULL.getCode(),"access_token拉取失败,请重新登录!");// 刷新accesstokenMap refreshToken = WeChatLoginUtil.refreshToken(ThirdPartyLoginEnum.WeChatEnum.AppID.getCode(), (String) t_token.get("refresh_token"));AssertException.isNullObject(refreshToken, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(refreshToken.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + refreshToken.get("errmsg") + ",请重新登录!");// 使用token交换获取用户信息String userInfo = WeChatLoginUtil.getUserInfo(refreshToken);return JsonUtil.fromJson(userInfo, Map.class);}// 微信公众号方式获取用户信息@Overridepublic Map wxPublicGetUserInfo(String code, String state) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");// 判断state是否合法String stateStr = CacheUtil.get(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFState.getCode() + state);AssertException.assertException(StringUtils.isEmpty(code) || StringUtils.isEmpty(state) || StringUtils.isBlank(stateStr), AppTipMsgEnum.PARAM_NOT_NULL.getCode(), "非法操作,请重新登录!");// 用户授权后的code换取tokenMap t_token = WeChatLoginUtil.getAccessTokenByPublic(code, ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode(), ThirdPartyLoginEnum.PublicWeChatEnum.AppSecret.getCode());// 判断是否成功获取到了tokenAssertException.isNullObject(t_token, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(t_token.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + t_token.get("errmsg") + ",请重新登录!");AssertException.assertException(StringUtils.isEmpty((String) t_token.get("access_token")) || StringUtils.isEmpty((String) t_token.get("openid")), AppTipMsgEnum.PARAM_NOT_NULL.getCode(),"access_token拉取失败,请重新登录!");// 刷新accesstokenMap refreshToken = WeChatLoginUtil.refreshTokenByPublic(ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode(), (String) t_token.get("refresh_token"));AssertException.isNullObject(refreshToken, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(refreshToken.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + refreshToken.get("errmsg") + ",请重新登录!");// 使用token交换获取用户信息String userInfo = WeChatLoginUtil.getUserInfoByPublic(refreshToken);return JsonUtil.fromJson(userInfo, Map.class);}
}

至此代码就算完成了,不足之处欢迎指教
由于框架用不明白,不想去理解,感觉配置太麻烦了,花那个时间去研究框架,我都写完了。

公众平台的登录请看另一篇:公众平台–扫描微信二维码,关注后自动登录


http://chatgpt.dhexx.cn/article/fJcx6FWs.shtml

相关文章

二维码登陆

上一段时间研究微信公共账号,发现微信提供了一个扫码登陆验证的功能。近期头痛于经常忘记用户名密码,因此考虑是否可以结合这个功能,完成免密码登陆。百度后发现&#xff0c;有很多仁兄已经做过类似的功能了。 如这篇文章: 实现网站二维码扫描登录 仔细研究后&#xff0c;发现很…

二维码登录(三)扫码登录

承接上篇博客&#xff0c;在进行二维码生成之后&#xff0c;app进行扫码&#xff0c;扫码成功之后&#xff0c;手机点击登录&#xff0c;进行绑定登录关系&#xff0c;后台做自动关联与自动登录。 本文git地址&#xff1a;https://github.com/xvshu/qrlogin 1&#xff0c;扫码…

微信扫码登陆(1)---扫码登录流程讲解、获取授权登陆二维码

扫码登录流程讲解、获取授权登陆二维码 具体流程可以看微信官网的扫码登录文档 地址&#xff1a;准备工作 | 微信开放文档 其实官方文档已经讲的非常清楚而且讲的也很明白。 一、扫码登录流程讲解 1、首先准备工作 网站应用微信登录是基于OAuth2.0协议标准构建的微信OAut…

二维码扫码登录

项目结构 模块介绍 流程1 pc端&#xff1a;1:打开二维码登录网页index.html2:index.html调用GetQrCodeServlet3:GetQrCodeServlet干2件事 a:生成随机的uuid,是一个唯一标识&#xff0c;该标识贯穿整个流程 b:生成二维码图片&#xff0c;二维码信息&#xff1a;http://60.2…

扫码登录详解

目录 扫码流程分析 流程详解 步骤一&#xff1a;PC端准备二维码 步骤三&#xff1a;状态确认 token认证机制 扫码流程分析 1.扫码前&#xff0c;手机端已经是登陆状态&#xff0c;PC端显示一个二维码&#xff0c;等待扫描。 2.手机端打开应用&#xff0c;扫描PC端的二维码…

新增商品

1、在http代理设置&#xff0c;添加过滤参数&#xff1a; .*pusher\.*\/websocket.* .*/venilog/log/one .*\.(bmp|css|js|gif|ico|jpe?g|png|swf|woff) .*pusher\/info.* 2、启动http代理设置&#xff0c;录制脚本&#xff0c;将登陆和发布商品的脚本修改成’登陆‘&#x…

自定义商品分类,选择分类之后,添加商品附属性;仿淘宝后台添加商品附属性的价格和数量

效果图&#xff08;图片较大&#xff0c;加载较慢&#xff09; 页面部分&#xff1a; <div class"layui-form-item" id"add_attribute"><label class"layui-form-label">商品分类</label><div class"layui-input-i…

javaScript原生版购物车:全选、单选、全删、商品数量增减、计算总价、添加商品(代码)

题目&#xff1a; CSS代码如下&#xff1a; <style> *{ margin: 0px; padding: 0px; } .header,.content,.floot{ width: 800px; margin:0px auto; } .header ul li,.content ul li{ float: left; list-style: none; width: 100px; line-height: 100px; text-align: cen…

商品管理的新增

实现的功能如下&#xff1a; 点击新增弹出新增模态框通过下拉框绑定商品类别和商品单位保存新增 主要代码&#xff1a; 以上就是我的分享&#xff0c;如果有更好的方法或不懂得地方欢迎在评论区教导和提问喔&#xff01;

案例:实现在购物车中添加商品和删除购物车中指定商品的功能

一、向购物车中添加商品 1.1.创建AddCartServlet public class AddCartServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}SuppressWarnings(&q…

14.商品添加功能

商品用例的bean层 添加商品的用例实现首先要有封装商品的bean&#xff0c;还要有封装商品种类的bean。 封装商品种类的bean package cn.bingou.domain;/*** 商品种类的bean* author 吹静静**/ public class ProdCategory {private int id;private String cname;public ProdCate…

二十三、商城 - 商品录入-新增商品(11)

目录 &#x1f33b;&#x1f33b; 一、商品录入【选择商品分类】1.1 需求分析1.2 准备工作1.3 代码实现1.3.1 一级分类下拉选择框1.3.2 二级分类下拉选择框1.3.3 三级分类下拉选择框1.3.4 读取模板ID 二、商品录入【品牌选择】2.1 需求分析2.2 代码实现 三、商品录入【扩展属性…

java添加功能_商品添加功能的实现

返回的结果&#xff1a; package com.taotao.common.utils; import java.util.List; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** * 淘淘商城自定义响应结构 */ public class TaotaoResult { // 定义jackson对象…

把商品添加到购物车的方法

因为抢华为荣耀的缘故&#xff0c;研究了下京东添加商品到购物车的方法&#xff0c;具体步骤如下 一&#xff1a;打开商品页面&#xff0c;找到商品的id 例如这个商品的id就是1056970 二&#xff1a;把链接里面的http://gate.jd.com/InitCart.aspx?pid###&pcount1&pt…

php 商品模块添加商品属性,添加新商品

进入添加商品页后&#xff0c;如图1&#xff0c;2 添加新商品 图1 图2 促销价格前台表现 图3 图4 图5 附加价格前台表现 图6 添加新商品 图7 配件和关联商品前台表现形式 图8 图9 通用信息商品分类&#xff1a;商品分类是必填项&#xff0c;用于帮助客户找到需要的商品。如果您…

添加商品

添加商品 步骤分析: 1.在index.jsp添加一个超链接 跳转到add.jsp 2.add.jsp放入一个表单 3.表单提交到 AddProductServlet 封装数据 调用service完成保存操作 跳转到FindAllServlet (请求转发和重定向) 有表单使用的时候若使用请求转发会出现重复提交 方案1:重定向 …

十七、商品添加

&#xff08;1&#xff09;通过编程式导航跳转到商品添加页面 1. 在List.vue页面。点击添加商品&#xff0c;实现页面跳转 2. 创建商品添加组件Add.vue 3. 为Add组件添加路由 &#xff08;2&#xff09; 渲染添加页面的基本UI结构 使用到Alter警告和Steps 步骤条组件 1. 引入…

(三十)商品管理-添加商品(上传图片)

&#xff08;三十&#xff09;商品管理-添加商品(上传图片) 添加商品(上传图片)1.修改页面上添加连接/store/adminProduct?methodaddUI2.在addUI请求转发到 添加页面3.在表单页面上修改action : /store/addProductServlet提交方式: method"post"添加enctype属性: e…

【VUE项目实战】56、商品添加功能(六)-提交添加的商品

接上篇《55、商品添加功能&#xff08;五&#xff09;-商品内容模块》 上一篇我们完成了商品内容编辑模块的开发&#xff0c;也即是完成了商品所有的信息编辑&#xff0c;本篇我们就来开发提交商品所有信息到后台的功能。 一、要实现的效果 我们要实现点击“添加商品”的按钮…

淘淘商城第30讲——实现商品添加功能

经过上文的学习&#xff0c;我相信大家都应该知道了富文本编辑器的使用方法&#xff0c;我们能走到这步&#xff0c;实属不易&#xff0c;本文终于可以来实现商品添加这个功能了。 在item-add.jsp页面当中&#xff0c;当点击提交按钮后&#xff0c;会触发submitForm方法&#…