封装通用第三方平台用户表(微信开放平台)

2024-08-21 19:44

本文主要是介绍封装通用第三方平台用户表(微信开放平台),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一. 注册微信开放平台
      • 1.1 开发者资质认证
      • 1.2 应用申请
      • 1.3 配置应用
    • 二.通用数据库表设计
    • 三.入库实体类
    • 四. 对接第三方平台
    • 4.1 微信开放平台VO对象
      • 4.2 通用方法


我们的系统可能要对接很多第三方系统,为了便利用户授权使用和对多平台账户的管理。有必要设计通用第三方平台表。用来统一用户管理,将以微信开放平台为例

一. 注册微信开放平台

首先强调的是 微信公众号平台和微信开放平台不是一个东西。 微信开放平台主要用于自己的系统对接微信。 而微信公众号平台主要使用微信公众号,小程序等微信内部程序对接微信开放接口。 而微信公众测试号不可用于微信开放平台。 微信开放平台必须通过企业认证注册应用实体,才能任意配置回调域使用测试域。

微信开放平台
微信开放平台文档
微信公众号平台
微信公众号平台测试号申请
微信公众号平台文档

1.1 开发者资质认证

在这里插入图片描述
主体必须以公司为认证实体
在这里插入图片描述

1.2 应用申请

扫描件内容必须与网站应用名称、网站应用简介、应用官网完全对应。 审查非常严格,不要得过且过。
在这里插入图片描述

1.3 配置应用

sercet只会出现一次,谨慎保管。如果我们需要登录或支付,其对应的接口状态必须为已获得
在这里插入图片描述
回调域配置,当认证通过后,我们可以使用内网穿透域名进行测试。或者使用公司公网,用nginx代理到个人电脑上进行测试开发
在这里插入图片描述
注意,授权回调域不要加http://或https:// 前缀,直接写域名即可,其中阅读开放平台开发文档时,让填写回调地址,那必须在接口请求时追加http:// 或https:// 前缀


二.通用数据库表设计

在这里插入图片描述

-- 第三方平台万能表  可以不绑定用户
-- access_token移除,作为token不入库
-- 移除 refresh_token ,让前端携带access_token同时携带refresh_token,保证可以刷新token
drop table if exists thirdauth_user;
create table thirdauth_user
(id          bigint unsigned                           not null comment '主键'primary key,user_id     bigint unsigned default 0 comment '用户id',tenant_id   varchar(32)     default '' comment '租户id 子平台再多,也不可能超过100个',nickname    varchar(32)     default ''                null comment '昵称',avator      varchar(255)    default ''                null comment '头像地址',scope       varchar(255)    default ''                null comment '授权范围',platform    varchar(32)                               not null comment '第三方平台名称',openid      varchar(64)                               not null comment '第三方平台用户id',unionid     varchar(64)     default ''                null comment '第三方内部跨平台id',create_time datetime        default CURRENT_TIMESTAMP null comment '创建时间',update_time datetime        default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',is_delete   tinyint         default 0                 null comment '是否删除 0否 1是',unique `idx_platform_openid` (`platform`, `openid`)
) comment '用户第三方登录表';

三.入库实体类

/*** 用户第三方登录表* @TableName thirdauth_user*/
@TableName(value ="thirdauth_user")
@Data
public class ThirdauthUser implements Serializable {/*** 主键*/@TableIdprivate Long id;/*** 用户id*/@TableField(value = "user_id")private Long userId;/*** 租户id 内部系统哪个平台的用户id*/@TableField(value = "tenant_id")private Long tenantId;/*** 昵称*/@TableField(value = "nickname")private String nickname;/*** 头像地址*/@TableField(value = "avator")private String avator;/*** 第三方平台名称*/@TableField(value = "platform")private String platform;/*** 第三方平台用户id*/@TableField(value = "openid")private String openid;/*** 第三方内部跨平台id*/@TableField(value = "unionid")private String unionid;/*** scope*/@TableField(value = "scope")private String scope;/*** 创建时间*/@TableField(value = "create_time")private LocalDateTime createTime;/*** 更新时间*/@TableField(value = "update_time")private LocalDateTime updateTime;/*** 是否删除 0否 1是*/@TableField(value = "is_delete")@TableLogic(value = "0",delval = "1")private Integer isDelete;@TableField(exist = false)private static final long serialVersionUID = 1L;
}

四. 对接第三方平台

每个平台返回的数据总有差异,我们需要各种vo来协调,最后都归于上述实体类入库。这里仅列出微信开放平台的封装。

4.1 微信开放平台VO对象

/*** @author YuanJie* @date 2024/8/20 下午2:32*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class WeChatVO {/*** 用户授权唯一标识*/private String openid;/*** 用户授权的access_token*/private String access_token;/*** access_token接口调用凭证超时时间,单位(秒)*/private Long expires_in;/*** 用户昵称*/private String nickname;/*** 用户头像*/private String headimgurl;/*** 用户刷新access_token  30天有效*/private String refresh_token;/*** 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID*/private String unionid;/*** 授权资料*/private String scope;
}

4.2 通用方法

/*** @author YuanJie* @date 2024/6/20 下午2:02*/
@RestController
@RequestMapping("/oauth2/wx")
@Slf4j
@ApiOperation(value = "oauth2", tags = "oauth2")
public class WXController extends BaseController {@Value("${oauth2.wx.appid}")private String appid;@Value("${oauth2.wx.appSecret}")private String appSecret;@Resourceprivate ThirdauthUserService thirdauthUserService;@Resourceprivate RestTemplate restTemplate;private final List<String> states = Collections.synchronizedList(new ArrayList<>());private final ObjectMapper objectMapper = new ObjectMapper();private final String WX_PREFIX = "wx";/*** 127.0.0.1:8080/oauth2/wx/code?backendUrl=http://xxxxo.com/oauth2/wx/callback** @param request* @param response* @param backendUrl* @throws IOException*/@ApiOperation("获取微信code")@GetMapping("/code")public void getWxCode(HttpServletRequest request,HttpServletResponse response,@RequestParam("backendUrl") String backendUrl) throws IOException {String state = UUID.randomUUID().toString().replace("-", "");this.states.add(state);// 回调地址直接填 下面的getCallback()方法。让微信直接回调下面的方法,这里回调地址必须加http https 前缀String url = "https://open.weixin.qq.com/connect/qrconnect?" +"appid=" + appid +"&redirect_uri=" + UriEncoder.encode(backendUrl) +"&response_type=code" +"&scope=snsapi_login" +"&state=" + state + "#wechat_redirect";response.sendRedirect(url);}/*** 供微信调用* 获取access_token** @param code*/@ApiOperation("获取access_token")@GetMapping("/callback")public AjaxResult getCallback(@RequestParam("code") String code, @RequestParam("state") String state) throws JsonProcessingException {// 校验stateif (!this.states.contains(state)) {return error();}this.states.remove(state);// 获取access_tokenString url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +"appid=" + appid +"&secret=" + appSecret +"&code=" + code +"&grant_type=authorization_code";ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);WeChatVO weChatVO = objectMapper.readValue(forEntity.getBody(), WeChatVO.class);if (weChatVO == null) {return error("获取微信信息异常");}// 获取用户信息准备入库WeChatVO userInfo = setUserInfo(weChatVO.getAccess_token(), weChatVO.getRefresh_token(), weChatVO.getOpenid());log.info("当前微信用户信息:{}", objectMapper.writeValueAsString(weChatVO));// 返回tokenreturn success(userInfo);}/*** 请求用户信息** @param accessToken* @param refreshToken* @param openid*/private WeChatVO setUserInfo(String accessToken, String refreshToken, String openid) throws JsonProcessingException {// 校验token是否有效 并刷新tokenaccessToken = checkToken(accessToken, refreshToken, openid);// 请求用户信息String userInfo = "https://api.weixin.qq.com/sns/userinfo?" +"access_token=" + accessToken +"&openid=" + openid;ResponseEntity<String> forEntity = restTemplate.getForEntity(userInfo, String.class);WeChatVO weChatVO = objectMapper.readValue(forEntity.getBody(), WeChatVO.class);if (weChatVO == null) {throw new RuntimeException("获取微信信息异常");}weChatVO.setAccess_token(accessToken);weChatVO.setRefresh_token(refreshToken);// 保存到数据库ThirdauthUser thirdauthUser = new ThirdauthUser();thirdauthUser.setPlatform(WX_PREFIX);thirdauthUser.setAvator(weChatVO.getHeadimgurl());BeanUtils.copyProperties(weChatVO, thirdauthUser);thirdauthUserService.saveOrUpdate(thirdauthUser,Wrappers.lambdaQuery(ThirdauthUser.class).eq(ThirdauthUser::getOpenid, weChatVO.getOpenid()).eq(ThirdauthUser::getPlatform, WX_PREFIX));return weChatVO;}/*** 校验token是否有效 并返回刷新的token** @param accessToken* @param refreshToken* @param openid*/private String checkToken(String accessToken, String refreshToken, String openid) throws JsonProcessingException {String checkToken = "https://api.weixin.qq.com/sns/auth?" +"access_token=" + accessToken +"&openid=" + openid;ResponseEntity<String> forEntity = restTemplate.getForEntity(checkToken, String.class);String body = forEntity.getBody();Map map = objectMapper.readValue(body, Map.class);if (map.get("errcode").equals(0)) {return refreshToken(refreshToken);}throw new RuntimeException("token失效,请重新登录");}/*** 刷新token 若refreshToken失效,则重新登录** @param refreshToken* @return*/private String refreshToken(String refreshToken) throws JsonProcessingException {String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?" +"appid=" + appid +"&grant_type=refresh_token" +"&refresh_token=" + refreshToken;ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);WeChatVO weChatVO = objectMapper.readValue(forEntity.getBody(), WeChatVO.class);if (weChatVO == null) {throw new RuntimeException("刷新token失败,refreshToken已过期,请重新登录");}return weChatVO.getAccess_token();}

在这里插入图片描述

这篇关于封装通用第三方平台用户表(微信开放平台)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094110

相关文章

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

MySQL 用户创建与授权最佳实践

《MySQL用户创建与授权最佳实践》在MySQL中,用户管理和权限控制是数据库安全的重要组成部分,下面详细介绍如何在MySQL中创建用户并授予适当的权限,感兴趣的朋友跟随小编一起看看吧... 目录mysql 用户创建与授权详解一、MySQL用户管理基础1. 用户账户组成2. 查看现有用户二、创建用户1. 基

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

Redis迷你版微信抢红包实战

《Redis迷你版微信抢红包实战》本文主要介绍了Redis迷你版微信抢红包实战... 目录1 思路分析1.1hCckRX 流程1.2 注意点①拆红包:二倍均值算法②发红包:list③抢红包&记录:hset2 代码实现2.1 拆红包splitRedPacket2.2 发红包sendRedPacket2.3 抢

java对接第三方接口的三种实现方式

《java对接第三方接口的三种实现方式》:本文主要介绍java对接第三方接口的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录HttpURLConnection调用方法CloseableHttpClient调用RestTemplate调用总结在日常工作