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

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

相关文章

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

Java中的登录技术保姆级详细教程

《Java中的登录技术保姆级详细教程》:本文主要介绍Java中登录技术保姆级详细教程的相关资料,在Java中我们可以使用各种技术和框架来实现这些功能,文中通过代码介绍的非常详细,需要的朋友可以参考... 目录1.登录思路2.登录标记1.会话技术2.会话跟踪1.Cookie技术2.Session技术3.令牌技

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

Mysql中的用户管理实践

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

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

使用JavaConfig配置Spring的流程步骤

《使用JavaConfig配置Spring的流程步骤》JavaConfig是Spring框架提供的一种基于Java的配置方式,它通过使用@Configuration注解标记的类来替代传统的XML配置文... 目录一、什么是 JavaConfig?1. 核心注解2. 与 XML 配置的对比二、JavaConf

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

Java对接Dify API接口的完整流程

《Java对接DifyAPI接口的完整流程》Dify是一款AI应用开发平台,提供多种自然语言处理能力,通过调用Dify开放API,开发者可以快速集成智能对话、文本生成等功能到自己的Java应用中,本... 目录Java对接Dify API接口完整指南一、Dify API简介二、准备工作三、基础对接实现1.

Spring Boot Controller处理HTTP请求体的方法

《SpringBootController处理HTTP请求体的方法》SpringBoot提供了强大的机制来处理不同Content-Type​的HTTP请求体,这主要依赖于HttpMessageCo... 目录一、核心机制:HttpMessageConverter​二、按Content-Type​处理详解1.