当前位置: 首页 > news >正文

JAVA(SpringBoot)对接微信登录

目录

1 申请测试账号

1.1 登录测试平台

1.2 配置接口配置信息

​编辑

1.3 配置JS接口安全域名

1.4 配置网页授权获取用户基本信息

 2:接口代码

 2.1 微信登录流程

2.2 依赖导入:

2.2.1 工具类:

2.3 创建微信用户实体类

2.4 接口功能

3 测试



1 申请测试账号

1.1 登录测试平台

链接: 微信公众平台测试

1.2 配置接口配置信息

在这一步,需要拥有能接入公网的服务器,或者利用内网穿透将自己的接口暴漏给微信,让微信的回调能成功访问到我们的接口

在可以将我们的接口暴漏在公网的前提下,我们可以书写接口配置接口配置信息的URL:(注意:这里只是简单配置URL,未添加验证微信服务器流程,详细配置请参考:点击进入)

import javax.servlet.http.HttpServletRequest;@RestController
@RequestMapping("/weChat")
public class WeChatController{@GetMapping("/verifyToken")public String verifyToken(HttpServletRequest request) {return request.getParameter("echostr");}}

比如我们的服务器地址是 119.3.248.100 ,上述服务部署在了该服务器8080端口上,那么按照上述代码的路径,URL就可配置为:http://119.3.248.100:8080/weChat/verifyToken (有域名使用域名即可)

1.3 配置JS接口安全域名

在测试公众号中,可以使用 IP + 端口 的形式设置安全域名,这里的域名填写上述服务你所部署的服务器地址即可 

1.4 配置网页授权获取用户基本信息

 这里的授权回调页面域名和JS接口安全域名保持一致即可


 2:接口代码

 2.1 微信登录流程

微信客户端发送登录请求 -> 访问微信授权接口 -> 微信回调,j将授权code发送到我们的服务器 -> 通过code,appid,appsecret获取微信针对该用户的accsess_token,openid等信息-> 通过accsess_token,openid获取用户信息

2.2 依赖导入:

在下叙代码中使用到了hutool的工具类,swagger的工具类,通过maven的pom文件导入:(注:实体类使用了一些mybatis-plus的注解,如无用删除即可)

<!--        hutool工具依赖--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version></dependency><!-- Swagger3 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>3.0.0</version></dependency><!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.3</version></dependency>

2.2.1 工具类:

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;/*** 微信登录工具类** @author * @date 2023/11/1 15:28*/
public class WeiXinUtil {private static final String appId = "xxxx";private static final String appsecret = "xxxx";private static final String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";private static final String redirectUrl = "http://xxxxx/v1/login/getAccessToken";private static final String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";private static final String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token";private static final String getUserInfo = "https://api.weixin.qq.com/sns/userinfo";/*** 获取微信授权code* @param state 附加信息* @return*/public static String getCode(String state) {try {StringBuffer url = new StringBuffer();url.append("redirect:").append(getCodeUrl).append("?appid=").append(appId).append("&redirect_uri=").append(URLEncoder.encode(redirectUrl, "UTF-8")).append("&response_type=code&scope=snsapi_userinfo&state=").append(state).append("#wechat_redirect");return url.toString();} catch (UnsupportedEncodingException e) {throw new RuntimeException("URL格式化异常");}}/*** 获取微信AccessToken* @param code 用户code* @return*/public static Map<?, ?> getAccessToken(String code) {StringBuffer url = new StringBuffer();url.append(getAccessTokenUrl).append("?appid=").append(appId).append("&secret=").append(appsecret).append("&code=").append(code).append("&grant_type=authorization_code");String rs = HttpUtil.get(url.toString());Map map = JSONObject.parseObject(rs, Map.class);if (null == map.get("errcode")) {return map;} else {throw new RuntimeException("获取access_token出错");}}/*** 刷新AccessToken* @param refreshToken* @return*/public static Map refreshToken(String refreshToken) {StringBuffer url = new StringBuffer();url.append(refreshTokenUrl).append("?appid=").append(appId).append("&grant_type=refresh_token&refresh_token=").append(refreshToken);String rs = HttpUtil.get(url.toString());Map map = JSONObject.parseObject(rs, Map.class);if (null == map.get("errcode")) {return map;} else {throw new RuntimeException("刷新access_token出错");}}/*** 获取用户信息* @param accessToken* @param openid* @return*/public static String getUserInfo(String accessToken, String openid) {StringBuffer url = new StringBuffer();url.append(getUserInfo).append("?access_token=").append(accessToken).append("&openid=").append(openid).append("&lang=zh_CN");String rs = HttpUtil.get(url.toString());return rs;}
}

2.3 创建微信用户实体类


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/**** 微信用户信息* @author * @date 2023/11/1 16:20*/
@TableName(value = "wx_user")
@Data
public class WXUser implements Serializable {private static final long serialVersionUID = -40356785423868312L;@TableId(type = IdType.AUTO)private Long id;/*** 系统用户id*/private Long userId;/*** 用户的唯一标识*/private String openid;/*** access_token*/private String accessToken;/*** refresh_token*/private String refreshToken;/*** 用户昵称*/private String nickname;/*** 性别(0未知,1男性,2女性)*/private String sex;/*** 用户个人资料填写的省份*/private String province;/*** 普通用户个人资料填写的城市*/private String city;/*** 国家,如中国为CN*/private String country;/*** 用户头像*/private String headimgurl;/*** 用户特权信息,json 数组*/private String privilege;/****/private String unionid;private Date createTime;private Date updateTime;private Long createBy;private Long updateBy;
}

2.4 接口功能

import javax.servlet.http.HttpServletRequest;@Controller
@RequestMapping("/weChat")
public class WeChatController{@ResponseBody@GetMapping("/verifyToken")@ApiOperation("微信Token验证")public String verifyToken(HttpServletRequest request) {return request.getParameter("echostr");}@GetMapping("/getCode")@ApiOperation("获取微信code")public String weiXinLogin(@RequestParam(defaultValue = "123") String state) {return WeiXinUtil.getCode(state);}@ResponseBody@GetMapping("/getAccessToken")@ApiOperation("获取token")public String getAccessToken(@RequestParam String code) {Map result = WeiXinUtil.getAccessToken(code);String accessToken = result.get("access_token").toString();String refreshToken = result.get("refresh_token").toString();String openid = result.get("openid").toString();WXUser wxUser = new WXUser();wxUser.setAccessToken(accessToken);wxUser.setRefreshToken(refreshToken);wxUser.setCreateTime(new Date());wxUser.setUserId(1L);wxUser.setOpenid(openid);wxUserService.save(wxUser);return "<h1>看样子成功了,没你事了退下吧</h1>";}@ResponseBody@GetMapping("/refreshToken")@ApiOperation("刷新token")public R refreshToken() {Long userId = 1L;WXUser wxUser = wxUserService.getOne(new LambdaUpdateWrapper<WXUser>().eq(WXUser::getUserId, userId));Map result = WeiXinUtil.refreshToken(wxUser.getRefreshToken());String accessToken = result.get("access_token").toString();String refreshToken = result.get("refresh_token").toString();WXUser wxUserUpdate = new WXUser();wxUserUpdate.setId(wxUser.getId());wxUserUpdate.setAccessToken(accessToken);wxUserUpdate.setRefreshToken(refreshToken);wxUserUpdate.setUpdateTime(new Date());wxUserService.updateById(wxUserUpdate);return R.data(accessToken);}@ResponseBody@GetMapping("/getUserInfo")@ApiOperation("获取用户信息")public R getUserInfo() {Long userId = 1L;WXUser wxUser = wxUserService.getOne(new LambdaUpdateWrapper<WXUser>().eq(WXUser::getUserId, userId));String accessToken = wxUser.getAccessToken();String openid = wxUser.getOpenid();String userInfoJsom = WeiXinUtil.getUserInfo(accessToken, openid);WXUser userInfo = JSONObject.parseObject(userInfoJsom, WXUser.class);userInfo.setId(wxUser.getId());userInfo.setUpdateTime(new Date());wxUserService.updateById(userInfo);return R.data(userInfo);}}

3 测试

微信扫码关注测试公众号

生成一个二维码调用获取code的接口,百度搜索  将获取code的URL路径填入码,手机微信扫码即可 : 草料文本二维码生成器,微信通过此入口即可访问获取code的页面, 注意:一定要使用手机微信客户端扫码二维码

流程:

获取code中的 redirect_uri 参数可以配置为我们的微信登录接口,这里为了演示功能,配置成了获取access_token 的接口

1. 通过获取code的接口,微信会通过我们配置的redirect_uri参数回调我们的接口,并会携带上code参数,同时注意此接口不要添加@ResponseBody 的注解

2. 微信回调获取access_token的接口,我们可以获取到access_token,refresh_token,openid这三个重要参数,这也是获取用户个人信息的关键

3. 刷新access_token的步骤可省略,有需要时可以调用此功能

4. 获取用户信息,这里获取用户信息的前提是我们在获取code的接口中,参数中的授权范围参数写为snsapi_userinfo 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • docker compose build 怎么才能只构建其中一个服务的镜像
  • 基于微信小程序+SpringBoot+Vue的儿童预防接种预约系统(带1w+文档)
  • 夯实数字经济的“新基建”-基于大数据与区块链技术的新型基础设施
  • LangChain4j-RAG基础
  • Linux相关指令
  • Apache DolphinScheduler Worker Task执行原理解析
  • 校车购票小程序的设计
  • Perl脚本学习(一)-- 基础语法
  • 17 敏捷开发—Scrum(2)
  • 微信小程序根据动态权限展示tabbar
  • ChatGPT:@JSONField 有什么用
  • 【LeetCode】字母异位词分组
  • [Meachines] [Easy] Blocky Jar包反编译
  • 【HarmonyOS】应用推送使用个推SDK如何实现?
  • MySQL面试篇章—MySQL锁机制
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • Apache Zeppelin在Apache Trafodion上的可视化
  • css系列之关于字体的事
  • EventListener原理
  • gcc介绍及安装
  • JSDuck 与 AngularJS 融合技巧
  • Laravel 中的一个后期静态绑定
  • Magento 1.x 中文订单打印乱码
  • Markdown 语法简单说明
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Vue全家桶实现一个Web App
  • 代理模式
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 多线程事务回滚
  • 理清楚Vue的结构
  • 三栏布局总结
  • 深度解析利用ES6进行Promise封装总结
  • 找一份好的前端工作,起点很重要
  • postgresql行列转换函数
  • # Panda3d 碰撞检测系统介绍
  • # Redis 入门到精通(九)-- 主从复制(1)
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (4)Elastix图像配准:3D图像
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (三)elasticsearch 源码之启动流程分析
  • (三分钟)速览传统边缘检测算子
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (四)js前端开发中设计模式之工厂方法模式
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (转)菜鸟学数据库(三)——存储过程
  • (自用)gtest单元测试
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .bat批处理出现中文乱码的情况
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .gitignore文件_Git:.gitignore
  • .libPaths()设置包加载目录
  • .net 7 上传文件踩坑