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

陕西做网站公司哪家好网域名查询地址

陕西做网站公司哪家好,网域名查询地址,石家庄369招聘信息网,做贷款的网站有哪些在微服务架构中,用户登录和身份校验的处理方式确实与单体应用有所不同。在单体架构中,一旦用户通过身份验证,其会话信息可以在整个应用范围内共享,所有模块都能访问到用户信息。然而,在微服务架构下,每个服…

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

目录

网关实现路由

网关登录鉴权

鉴权思路

登录校验流程图

网关过滤器详解

实现网关过滤器

拦截器流程图

服务信息鉴权


网关实现路由

问题:每个微服务都有不同的地址或端口,入口不同,请求不同数据时要访问不同的入口,需要维护多个入口地址,前端无法调用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.hengruixuexiao.com/news/43210.html

相关文章:

  • 软件前端开发工程师长春seo排名扣费
  • 石景山区住房城乡建设委官方网站外贸seo网站
  • 在哪家网站做推广好电商平台
  • 软件设计师怎么考重庆seo排名收费
  • 烟台市最好的专业做网站的公司网站建设一条龙
  • 2017年做网站多少钱搜索引擎优化关键词选择的方法有哪些
  • 建设银行审计招聘网站优化系统软件
  • 网站登陆验证怎么用java做百度游戏中心app
  • wordpress 网站维护sem是什么牌子
  • 上海网站开发学校有哪些怎么做好网络推广销售
  • 网站建设进展情况汇报徐州网络推广服务
  • 兰州网站seo长尾关键词优化
  • 网站做微信支付功能站长工具百度
  • 专业彩票网站开发上海百度搜索优化
  • 做搜狗手机网站优化首安卓嗅探app视频真实地址
  • phpcms仿行业网站如何联系百度人工客服电话
  • 个人做网站报价社群运营
  • 减肥药 做网站营销无代码系统搭建平台
  • 江西做网站的公司公众号排名优化软件
  • 企业建设网站的方式有两种软文营销范文100字
  • 郑州东区做网站电话php免费开源crm系统
  • 我家云物业管理系统冯耀宗seo教程
  • php怎么做网站快无锡网站制作
  • ie浏览器打开怎么是2345网址导航无线网络优化是做什么的
  • 如何做后台网站的教程站长之家查询域名
  • 做网站的感想seo推广软件品牌
  • 公司企业网站模板下载谷歌搜索引擎网址
  • 山东德州网站建设哪家最好seo 优化思路
  • 日本设计公司网站推广文案怎么写
  • 网站开发四点注意事项广州百度关键词推广