尚品汇-网关过滤用户请求、登录流程(三十五)

2024-08-21 03:52

本文主要是介绍尚品汇-网关过滤用户请求、登录流程(三十五),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录:

(1)用户认证与服务网关整合

(2)server-gateway网关配置  

(3)在服务网关中判断用户登录状态

(4)登录流程

(1)用户认证与服务网关整合

 实现思路

  1. 所有请求都会经过服务网关,服务网关对外暴露服务,不管是api异步请求还是web同步请求都走网关,在网关进行统一用户认证
  2. 既然要在网关进行用户认证,网关得知道对哪些url进行认证,所以我们得对url制定规则
  3. Web页面同请求(如:*.html),我采取配置白名单的形式,凡是配置在白名单里面的请求都是需要用户认证的(注:也可以采取域名的形式,方式多多)
  4. Api接口异步请求的,我们采取url规则匹配,如:/api/**/auth/**,如凡是满足该规则的都必须用户认证

redis:

  host: 192.168.200.129

  port: 6379

  database: 0

  timeout: 1800000

  password:

 

authUrls:

  url: trade.html,myOrder.html,list.html

(2)server-gateway网关配置  

pom.xml

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-data-redis-reactive</artifactId>

</dependency>

在网关中添加redis的配置类。

注意需要引入RedisConfig配置类:因为这个模块没有扫描service-util

server-gateway 项目中添加一个过滤器

ResultCodeEnum :

package com.atguigu.gmall.common.result;import lombok.Getter;/*** 统一返回结果状态信息类**/
@Getter
public enum ResultCodeEnum {SUCCESS(200,"成功"),FAIL(201, "失败"),SERVICE_ERROR(2012, "服务异常"),ILLEGAL_REQUEST( 204, "非法请求"),PAY_RUN(205, "支付中"),LOGIN_AUTH(208, "未登陆"),PERMISSION(209, "没有权限"),SECKILL_NO_START(210, "秒杀还没开始"),SECKILL_RUN(211, "正在排队中"),SECKILL_NO_PAY_ORDER(212, "您有未支付的订单"),SECKILL_FINISH(213, "已售罄"),SECKILL_END(214, "秒杀已结束"),SECKILL_SUCCESS(215, "抢单成功"),SECKILL_FAIL(216, "抢单失败"),SECKILL_ILLEGAL(217, "请求不合法"),SECKILL_ORDER_SUCCESS(218, "下单成功"),COUPON_GET(220, "优惠券已经领取"),COUPON_LIMIT_GET(221, "优惠券已发放完毕"),;private Integer code;private String message;private ResultCodeEnum(Integer code, String message) {this.code = code;this.message = message;}
}
package com.atguigu.gmall.gateway.filter;@Component
public class AuthGlobalFilter implements GlobalFilter{@Autowiredprivate RedisTemplate redisTemplate;// 匹配路径的工具类private AntPathMatcher antPathMatcher = new AntPathMatcher();//获取nacos配置文件中的配置@Value("${authUrls.url}")private String authUrls;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 获取到请求对象ServerHttpRequest request = exchange.getRequest();// 获取UrlString path = request.getURI().getPath();// 如果是内部接口,则网关拦截不允许外部访问!if (antPathMatcher.match("/**/inner/**",path)){ServerHttpResponse response = exchange.getResponse();return out(response,ResultCodeEnum.PERMISSION);}// 获取用户IdString userId = getUserId(request);//token被盗用if("-1".equals(userId)) {ServerHttpResponse response = exchange.getResponse();return out(response,ResultCodeEnum.PERMISSION);}// 用户登录认证//api接口,异步请求,校验用户必须登录if(antPathMatcher.match("/api/**/auth/**", path)) {if(StringUtils.isEmpty(userId)) {ServerHttpResponse response = exchange.getResponse();return out(response,ResultCodeEnum.LOGIN_AUTH);}}// 验证urlfor (String authUrl : authUrls.split(",")) {// 当前的url包含登录的控制器域名,但是用户Id 为空!if (path.indexOf(authUrl)!=-1 && StringUtils.isEmpty(userId)){ServerHttpResponse response = exchange.getResponse();//303状态码表示由于请求对应的资源存在着另一个URI,应使用重定向获取请求的资源response.setStatusCode(HttpStatus.SEE_OTHER);//设置地址location   originUrl当前请求的地址   response.getHeaders().set(HttpHeaders.LOCATION,"http://www.gmall.com/login.html?originUrl="+request.getURI());// 重定向到登录return response.setComplete();}}//存储userId到请求中// 将userId 传递给后端if (!StringUtils.isEmpty(userId)){request.mutate().header("userId",userId).build();// 将现在的request 变成 exchange对象return chain.filter(exchange.mutate().request(request).build());}return chain.filter(exchange);}/*** 获取当前登录用户id* @param request* @return*/
//public static String getUserId(HttpServletRequest request) {
//    String userId = request.getHeader("userId");
//    return StringUtils.isEmpty(userId) ? "" : userId;
// }

(3)在服务网关中判断用户登录状态

在网关中如何获取用户信息:

  1. 从cookie中获取(如:web同步请求)
  2. 从header头信息中获取(如:异步请求)

如何判断用户信息合法:

登录时我们返回用户token,在服务网关中获取到token后,我在到redis中去查看用户id,如果用户id存在,则token合法,否则不合法,同时校验ip,防止token被盗用。

 

/*** 获取当前登录用户id* @param request* @return*/
private String getUserId(ServerHttpRequest request) {String token = "";//头信息List<String> tokenList = request.getHeaders().get("token");if(null  != tokenList) {token = tokenList.get(0);} else {//从cookie中获取MultiValueMap<String, HttpCookie> cookieMultiValueMap =  request.getCookies();HttpCookie cookie = cookieMultiValueMap.getFirst("token");if(cookie != null){token = URLDecoder.decode(cookie.getValue());}}//获取数据if(!StringUtils.isEmpty(token)) {//从Redis中获取String userStr = (String)redisTemplate.opsForValue().get("user:login:" + token);//转换 JSONObject userJson = JSONObject.parseObject(userStr);//获取ipString ip = userJson.getString("ip");//获取请求的ipString curIp = IpUtil.getGatwayIpAddress(request);//校验token是否被盗用if(ip.equals(curIp)) {return userJson.getString("userId");} else {//ip不一致return "-1";}}return "";
}

 

输入信息out 方法

// 接口鉴权失败返回数据
private Mono<Void> out(ServerHttpResponse response,ResultCodeEnum resultCodeEnum) {// 返回用户没有权限登录Result<Object> result = Result.build(null, resultCodeEnum);byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);//获取DataBuffer DataBuffer wrap = response.bufferFactory().wrap(bits);//乱码处理response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");// 输入到页面return response.writeWith(Mono.just(wrap));
}

当退出登录后,点击 

跳转到登录页面

登录后:

会跳转到点击的页面

后面就可以用了

(4)登录流程

 

 

退出:

 

网关中的过滤器:如果有多个过滤器可以实现Order,执行过滤器的执行顺序,谁的越小谁就先执行

 

这篇关于尚品汇-网关过滤用户请求、登录流程(三十五)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S