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

湖南营销网站建设设计十大免费网页制作平台

湖南营销网站建设设计,十大免费网页制作平台,wordpress 公告,wordpress 仿 模板下载在微服务架构中,用户登录和身份校验的处理方式确实与单体应用有所不同。在单体架构中,一旦用户通过身份验证,其会话信息可以在整个应用范围内共享,所有模块都能访问到用户信息。然而,在微服务架构下,每个服…

在微服务架构中,用户登录和身份校验的处理方式确实与单体应用有所不同。在单体架构中,一旦用户通过身份验证,其会话信息可以在整个应用范围内共享,所有模块都能访问到用户信息。然而,在微服务架构下,每个服务独立部署且通常运行在不同的进程中,因此需要一种机制来确保用户的身份信息能够在各个微服务之间安全、高效地传递和验证。

目录

 

网关实现路由

网关登录鉴权

鉴权思路

登录校验流程图

网关过滤器详解

实现网关过滤器

拦截器流程图

服务信息鉴权


 

网关实现路由

问题:每个微服务都有不同的地址或端口,入口不同,请求不同数据时要访问不同的入口,需要维护多个入口地址,前端无法调用nacos,无法实时更新服务列表。

解决方案:采用微服务网关,数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发。

在微服务中新建一个网关模块,作为网关微服务

引入依赖(需要加入nacos依赖,让nacos管理)

 <dependencies><!--common--><dependency><groupId>com.heima</groupId><artifactId>hm-common</artifactId><version>1.0.0</version></dependency><!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos discovery--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency></dependencies>

application.yaml文件,配置路由

  gateway:routes:- id: item # 路由规则id,自定义,唯一uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务- Path=/items/**,/search/** # 这里是以请求路径作为判断规则

经测试成功

网关登录鉴权

问题:单体架构时我们只需要完成一次用户登录、身份校验,就可以在所有业务中获取到用户信息。但是,在微服务中,每个微服务都独立部署,一般只有用户微服务能校验登录信息,事实上,这是不安全的。

解决方案:既然网关是所有微服务的入口,一切请求都需要先经过网关。我们完全可以把登录校验的工作放到网关去做。

鉴权思路

登录是基于JWT来实现的,校验JWT的算法复杂,而且需要用到秘钥。我们不可能让个微服务都需要知道JWT的秘钥,不安全。也不可能每个微服务重复编写登录校验代码、权限校验代码,麻烦。

所以,我们在网关和用户服务保存秘钥,开发登录校验功能。

登录校验流程图

我们可以看到:前端——网关——后端服务

我们在网关层去实现过滤请求。

网关过滤器详解

Gateway内部工作的基本原理:

如图所示:

  1. 客户端请求进入网关后由HandlerMapping对请求做判断,找到与当前请求匹配的路由规则(Route),然后将请求交给WebHandler去处理

  2. WebHandler则会加载当前路由下需要执行的过滤器链(Filter chain),然后按照顺序逐一执行过滤器(后面称为Filter

  3. 图中Filter被虚线分为左右两部分,是因为Filter内部的逻辑分为prepost两部分,分别会在请求路由到微服务之前之后被执行

  4. 只有所有Filterpre逻辑都依次顺序执行通过后,请求才会被路由到微服务

  5. 微服务返回结果后,再倒序执行Filterpost逻辑

  6. 最终把响应结果返回

反正就是:我们需要在NettyRoutingFilter过滤器之前,在发起Request时,即pre时,定义一个过滤器,进行网关登录校验。

实现网关过滤器

我们采用全局过滤器,作用范围是所有路由,即GlobalFilter。

package com.hmall.gateway.filters;import com.hmall.common.exception.UnauthorizedException;
import com.hmall.gateway.config.AuthProperties;
import com.hmall.gateway.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.List;@RequiredArgsConstructor
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {private final AuthProperties authProperties;private final JwtTool jwtTool;private final AntPathMatcher antPathMatcher = new AntPathMatcher();/*** 过滤器* @param exchange* @param chain* @return*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1.获取请求对象ServerHttpRequest request = exchange.getRequest();// 2.判断是否需要拦截if (isExclude(request.getPath().toString())) {// 放行return chain.filter(exchange);}// 3.获取tokenString token = null;List<String> headers = request.getHeaders().get("authorization");if (headers != null && !headers.isEmpty()) {token = headers.get(0);}// 4.解析tokenLong userId = null;try {userId = jwtTool.parseToken(token);} catch (UnauthorizedException e) {// 如果无效,拦截ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}// 5.获取用户信息String userInfo = userId.toString();ServerWebExchange swe = exchange.mutate().request(builder -> builder.header("user-info",userInfo )).build();// 6.放行return chain.filter(swe);}/*** 判断路径是否需要拦截* @param antPath* @return*/private boolean isExclude(String antPath) {for (String pathPattern : authProperties.getExcludePaths()) {if(antPathMatcher.match(pathPattern, antPath)){return true;}}return false;}// 优先级@Overridepublic int getOrder() {return 0;}
}

因为我采用了JWT令牌进行校验,所以引入了JWT工具类,进行令牌的获取与解析。

至于AuthProperties是配置了不需要鉴权就能访问的路径。

经测试,网关已经可以完成登录校验并获取登录用户身份信息。


问题:当网关将请求转发到微服务时,微服务如何获取用户身份,我们不可能每个微服务都写一个拦截器去得到用户身份信息。

解决方案:将用户信息以请求头的方式传递到下游微服务。然后微服务可以从请求头中获取登录用户信息(上述代码第五步已经完成了)。考虑到微服务内部可能很多地方都需要用到登录用户信息,因此我们可以利用SpringMVC的拦截器来实现登录用户信息获取,并存入ThreadLocal。

拦截器流程图

提供一个用于保存登录用户的ThreadLocal工具UserContext:

public class UserContext {private static final ThreadLocal<Long> tl = new ThreadLocal<>();/*** 保存当前登录用户信息到ThreadLocal* @param userId 用户id*/public static void setUser(Long userId) {tl.set(userId);}/*** 获取当前登录用户信息* @return 用户id*/public static Long getUser() {return tl.get();}/*** 移除当前登录用户信息*/public static void removeUser(){tl.remove();}
}

在公用模块下定义一个拦截器:

public class UserInfoInterceptor implements HandlerInterceptor {/*** 请求拦截器* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.获取请求头中的 用户信息String userInfo = request.getHeader("user-info");// 2.判断是否为空if (StringUtils.isNotBlank(userInfo)) {UserContext.setUser(Long.valueOf(userInfo));}// 3.放行return true;}/*** 响应拦截器* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserContext.removeUser();}
}

编写SpringMVC的配置类,配置登录拦截器:

@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());}
}

注意:这个配置类默认是不会生效的,基于SpringBoot的自动装配原理,我们要将其添加到resources目录下的META-INF/spring.factories文件中:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.hmall.common.config.MyBatisConfig,\com.hmall.common.config.MvcConfig

经测试,服务得到网关传递的用户身份信息。

服务信息鉴权

问题:因为之前编写的过滤器和拦截器功能,微服务可以轻松获取登录用户信息。但是,有时候请求到达微服务后还需要调用其它多个微服务。我们没有实现服务之间的用户身份信息的传递。

解决方案:由于微服务获取用户信息是通过拦截器在请求头中读取,因此要想实现微服务之间的用户信息传递,就必须在微服务发起调用时把用户信息存入请求头

因为我们之前微服务之间调用是基于OpenFeign来实现的,并不是我们自己发送的请求。所以我们可以采用Feign中提供的一个拦截器接口:feign.RequestInterceptor。

在公用模块下定义一个userInfoRequestInterceptor

    /*** feign请求拦截器 微服务之间的远程调用时,将当前登录用户的userId传递给目标服务* @return*/@Beanpublic RequestInterceptor userInfoRequestInterceptor() {return new RequestInterceptor() {public void apply(RequestTemplate requestTemplate) {Long userId = UserContext.getUser();if (userId != null) {requestTemplate.header("user-info", userId.toString());}}};}

总结:

  • 为了实现网关处简便的登录校验,我们采用了GlobalFilter
  • 为了实现网关传递用户信息到多个微服务,我们采用了UserInfoInterceptor
  • 为了实现微服务之间用户身份信息传递,我们采用了userInfoRequestInterceptor。

 

http://www.dtcms.com/wzjs/568783.html

相关文章:

  • php mysql网站开发教程php网站开发案例教程
  • 软件下载网站 知乎无锡微信网站推广
  • 南漳县建设局网站做外单网站亚马逊
  • 自己做网站统计工程建设网最新信息网站
  • 给别人做违法网站wordpress翻页函数
  • 提供邯郸做wap网站wap建站软件
  • 茶叶网站模板免费下载郑州seo优化外包顾问阿亮
  • 网站建设视觉营销房产抵押贷款
  • ps2017做网站服务器ip域名解析
  • 欧美网站建设排名建设一个普通网站需要多少钱
  • 淄博网站建设哪家好互联网创业就是做网站吗
  • 六安市 网站集约化建设大数据做网站
  • 中国建设银行安徽分行网站wordpress导航网
  • 用wordpress建立学校网站吗wordpress建站解析
  • 高端网站建设公司联系电话做家政在哪个网站找
  • html代码表白烟花特效徐州seo管理
  • 怎样在手机上做网站网上商城可行性分析报告
  • 建设官方企业网站深圳网站建设找哪家
  • 湖南智能网站建设哪里好个人+网站可以做导航吗
  • 网站建设步骤 教 程wordpress伪静态规则nginx
  • 南昌网站建设制作与维护龙泉驿最新消息
  • 网站全屏轮播怎么做网络服务器是指
  • 靖江网站定制西安中高风险地区
  • 网站开发服务流程推荐黄的网站
  • 怎么删除网站里的死链接做网站用jsp还是j2ee
  • 那个网站ppt做的比较好asp.net做网站如何展示界面
  • 青岛公司网站建设公司专业做网站的网站
  • 在线教育网站建设广州市研发网站建设平台
  • 设计网站免费下载网站建设问卷调查表
  • 网站开发公司上指定关键词seo报价