微信授权登录接口开发

news/2024/11/15 23:39:59/文章来源:https://www.cnblogs.com/lilyflower/p/18417331

微信登陆过程

在项目开发中,难免会遇到微信授权登录这一操作,本讲来讲一下微信登陆是如何实现的?

关于校验登录,有诸多方法,记录方法如下:

  • 使用Spring MVC提供的拦截器
  • 网关服务全局过滤器
  • 使用AOP面向横切面实现

对于使用Spring MVC提供的拦截器来实现,其大致的思路如下:

注意:

  1. 用户登录成功以后,会生成对应的token,并且会将登录用户的信息存储到Redis中(键:token 值:userInfo),然后将token返回给前端
  2. 需要在每一个业务微服务中定义拦截器,影响开发效率,代码维护性较低。(解决方案:可以将拦截器定义到公共的模块中)

对于使用网关服务的全局过滤器来完成校验登录, 需要开发全局过滤器(GlobalFilter)

对于使用AOP横切面完成统一登录校验逻辑,配合自定义注解,哪一个业务方法需要验证用户登录状态,就在该方法上添加自定义注解。

这里呢我们推荐使用第三种,因此对于有的服务来讲,是不需要客户端进行登陆操作就可以直接访问的,其自由度不高。我们可以使用自定义注解来完成登录的校验,这样对于有需要登录信息的接口我们只需要加上我们自定义的注解即可,对于不需要登录信息的接口就可以不用加自定义注解。

1. AOP实现登录校验步骤

1.1 自定义登陆注解

首先自定义一个注解,该注解为登陆注解。

注解作用:哪些需要登录才能访问必须要添加,那些需要获取到用户Id 也必须加这个注解。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Login {boolean required() default true;		// 是否必须要登录    
}

1.2 自定义切面类

@Aspect
@Component
public class LoginAspect {@Autowiredprivate RedisTemplate<String , String> redisTemplate;@SneakyThrows@Around("execution(* com.*.*.api.*.*(..)) && @annotation(Login)")	// 匹配方法上带有@Login注解的方法对其实现功能增强public Object loginAspect(ProceedingJoinPoint point, Login login){//  获取HttpServletRequest对象RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;HttpServletRequest request = sra.getRequest();String token = request.getHeader("token");//  判断是否需要登录if (login.required()){//  必须要登录,token 为空是抛出异常if (StringUtils.isEmpty(token)){throw new Exception(ResultCodeEnum.LOGIN_AUTH);   //  没有token 要抛出异常}//  如果token 不为空,从缓存中获取信息.String userInfoJSON =  this.redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);//  判断对象是否为空if (StringUtils.isEmpty(userInfoJSON)){throw new Exception(ResultCodeEnum.LOGIN_AUTH);            //  抛出异常信息}// 将用户信息存储到ThreadLocal中// AuthContextHolder 底层就是 ThreadLocalUserInfo userInfo = JSON.parseObject(userInfoJSON, UserInfo.class);AuthContextHolder.setUserId(userInfo.getId());AuthContextHolder.setUsername(userInfo.getNickname());}else {//  不需要强制登录,但是,有可能需用到用户信息.if (!StringUtils.isEmpty(token)){//  如果token 不为空,从缓存中获取信息.String userInfoJSON =  this.redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);if (!StringUtils.isEmpty(userInfoJSON)){//  将用户信息存储到ThreadLocal中UserInfo userInfo = JSON.parseObject(userInfoJSON, UserInfo.class);AuthContextHolder.setUserId(userInfo.getId());AuthContextHolder.setUsername(userInfo.getNickname());}}}try {// 执行目标方法并获取目标方法执行后的返回结果Object proceed = point.proceed();// 返回return proceed ;}catch (Throwable e) {e.printStackTrace();} finally {// 从ThreadLocal中删除数据,防止内存泄漏和移除AuthContextHolder.removeUserId();AuthContextHolder.removeUsername();}return null ;}
}

AuthContextHolder类:

/*** 获取当前用户信息帮助类*/
public class AuthContextHolder {private static ThreadLocal<Long> userId = new ThreadLocal<Long>();private static ThreadLocal<String> username = new ThreadLocal<String>();public static void setUserId(Long _userId) {userId.set(_userId);}public static Long getUserId() {return userId.get();// return 1L;}public static void removeUserId() {userId.remove();}public static void setUsername(String _username) {username.set(_username);}public static String getUsername() {return username.get();}public static void removeUsername() {username.remove();}
}

1.3 微信登陆流程介绍

参数说明:

1、前端调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。

2、后端调用 auth.code2Session 接口,换取用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账

号)和 会话密钥 session_key

3、之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意事项:

1、会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个

密钥

2、临时登录凭证 code 只能使用一次

配置WxMaService

WechatAccountConfig

定义一个实体类读取service-user-dev.yaml配置文件中关于微信开放平台的相关配置。

@Data
@ConfigurationProperties(prefix = "wechat.login")
public class WechatAccountConfig {private String appId;					//  公众平台的appdIdprivate String appSecret;				//  小程序微信公众平台秘钥
}// 启动类添加如下注解
@EnableConfigurationProperties(value = WechatAccountConfig.class)

配置文件中定义了微信授权登录的appId和appSecret

wechat:login:#小程序授权登录appId:   # 小程序微信公众平台appIdappSecret:   # 小程序微信公众平台api秘钥

WeChatMpConfig

WxMaService配置类

@Configuration
public class WeChatMpConfig {@Autowiredprivate WechatAccountConfig wechatAccountConfig;@Beanpublic WxMaService wxMaService(){WxMaDefaultConfigImpl wxMaConfig =  new WxMaDefaultConfigImpl();		        //  创建对象wxMaConfig.setAppid(wechatAccountConfig.getAppId());wxMaConfig.setSecret(wechatAccountConfig.getAppSecret());wxMaConfig.setMsgDataFormat("JSON");WxMaService service = new WxMaServiceImpl();		 //  创建 WxMaService 对象service.setWxMaConfig(wxMaConfig);					  //  给 WxMaService 设置配置选项return service;}}

登录接口开发

@Operation(summary = "小程序授权登录")
@GetMapping("/wxLogin/{code}")
public Result<Map<String , String>> wxLogin(@PathVariable String code) throws WxErrorException {Map<String , String> tokenInfo = wxLoginService.wxLogin(code) ;return Result.build(tokenInfo , ResultCodeEnum.SUCCESS) ;
}

获取登录用户的openId信息

public void wxLogin(String code) throws WxErrorException {//  获取从微信服务端返回的结果WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);// 获取openIdString openId = sessionInfo.getOpenid();UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openId));//  创建tokenString token = UUID.randomUUID().toString().replaceAll("-","");// 进行后续操作...从存入Redis中等业务
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/798670.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1 计算机系统

计算机系统抽象层次6 用户 可执行程序5 高级语言 C++ Java4 汇编语言 汇编代码3 系统软件 操作系统 /库代码2 机器 指令集架构(ISA)1 控制(控制怎么执行) 微代码 /硬连线0 数字逻辑(执行) 电路、门等Language Processor: 语言处理器 语言处理器的两个阶段:分析源程序 合成目…

人工智能生成合成内容标识办法(征求 意见稿)发布

当前国家发布的关于人工智能生成合成内容标识的法律法规有:《中华人民共和国网络安全法》、《互联网信息服务算法推荐管理规定》、《互联网信息服务深度合成管理规定》、《生成式人工智能服务管理暂定办法》等。 征求意见稿 2024年9月14日,国家网信办发布关于《人工智能生成合…

南沙信奥老师解题:1167:再求f(x,n)

​ 用递归函数求解。【输入】第一数是x的值,第二个数是n的值。【输出】函数值。【输入样例】 1 2 【输出样例】 0.40#include <iostream> #include <stdlib.h> using namespace std; double f(double x,double n) {if(n==1)return x/(1+x);elsereturn x/(n+f(x,n-…

概率分布深度解析:PMF、PDF和CDF的技术指南

本文将深入探讨概率分布,详细阐述概率质量函数(PMF)、概率密度函数(PDF)和累积分布函数(CDF)这些核心概念,并通过实际示例进行说明。 在深入探讨PMF、PDF和CDF之前,有必要先简要介绍两种常用的概率分布:正态分布和均匀分布。 正态分布: 也称为高斯分布或钟形曲线,正…

冒泡排序(重要!)

1.作用 比较数组中两个相邻的数,如果第一个数比第二个数大,则会交换位置。 每一次比较都会产出最大或是最小的数,下一轮则可以少一次排序,依次循环,直到结束 2.机制 冒泡排序分为两个循环,外层冒泡轮数(总的次数循环),而内层比较大小(两个数进行比较) 可以想象有三个…

Luogu P10812

题目描述 给定一根 \(1\) 到 \(N\) 的数轴。一开始有一个棋子在 \(N\)。每次棋子 \(x\) 可以跳到 \(x-1,x+1\) 或 \(x\) 的因子处(不能超出 \(1\) 到 \(N\))。 每个点只能到达一次。求棋子到达 \(1\) 的方案数。 思路 由于求倍数比因子简单,所以把问题变成从 \(1\) 到 \(N\)…

爬虫cookie的使用

cookie是一种由网站创建并存储在用户计算机上的小型文本文件。访问该网站时由浏览器返回给服务器。cookie主要作用是帮助网站记住用户信息,包括但不限于:会话管理,网站使用cookie识别用户的会话,以便用户在浏览网站时不需要重复登录。 个性化体验,通过存储用户的偏好设置,…

unity人工智能游戏、源码、教程(中秋特别版),完全免费和开源

三维虚拟世界的人工智能对话。 完全免费、完全开源、完整详细、通俗易懂。 我把游戏、游戏源码、教程(三合一)放到了夸克网盘: 链接:https://pan.quark.cn/s/65e22d51c1bb任何人不要和我说话,我不想跟任何人说话,因为我对现实世界的人类不感兴趣。谁跟我说话,我都不会理…

校招前的思考

又有了一次参加校招的机会,我希望校招这种活动,自己每参加一次,都能加深一次理解。校招前,我想思考清楚一个问题:企业为什么要校招?又有了一次参加校招的机会,我希望校招这种活动,自己每参加一次,都能加深一次理解。校招前,我想思考清楚一个问题:企业为什么要校招?…

江锐第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 学习博客园的基本知识,并介绍自己,自我认知姓名-学号 江锐-2022329301014一、个人简介 (1)基本信息 姓 名: 江锐 物 理 家 乡:湖北武汉 专 业: 电气工程及其自动化 网 络 家 乡:github,…

中秋快乐

最近北京的天气真不错 昨天出门,傍晚天渐渐黑了,抬头看见好圆整的月亮,才意识到中秋到了,没啥课天天放假已经对工作日假期没啥概念了。 祝大家中秋快乐! Lemon越听越很上头,特别是2019年演唱会版真的很有感觉, 还能学习一波假名。 又有点想去演唱会了,上次还是工体Shane…

白云龙期货投资-第七讲

10种经典的进出场方法2 2B法则跌破第三波上涨就以此为依据进场做空2B法则进场法操作要点 1,适合行情已经走完5浪: 2,跌破或突破5浪前高低点(次高低点)有效; 3,止损:次高低点与新高低点的二分之一处; 10种经典的进出场方法3 金牛断角射击之星金牛断角进场法操作要点 1,最好…