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

网站新闻公告表怎么做域名排名查询

网站新闻公告表怎么做,域名排名查询,1000并发视频网站,汽车案例网站前两期: 物流项目第一期(登录业务)-CSDN博客 物流项目第二期(用户端登录与双token三验证)-CSDN博客 为什么要有网关? 通过前面的课程我们已经完成了四个端的登录,但是我们并没有对登录后的请…

前两期:

物流项目第一期(登录业务)-CSDN博客

物流项目第二期(用户端登录与双token三验证)-CSDN博客 

为什么要有网关?

通过前面的课程我们已经完成了四个端的登录,但是我们并没有对登录后的请求中的token做校验,假设要做的话,是不是四个端每个端都需要实现?这样类似的代码就会重复,显然这并不是一个好的设计。

所以,通过Spring Cloud Gateway就可以接管所有来自客户端的请求,在此处做校验是最为合适的选择。

实际上,在网关中除了需要对token是否有效进行校验外,还需要对用户的是否有权限进行校验,比如说:司机不能登录到快递员端,快递员不能登录到司机端等。

自定义过滤器配置 

spring:gateway: routes:- id: sl-express-ms-web-manager #路由标识,需要唯一uri: lb://sl-express-ms-web-manager #最终请求转发的微服务,指定的是微服务名,并开启负载均衡predicates: #断言- Path=/manager/**filters: #配置过滤器- ManagerToken #自定义局部过滤器- StripPrefix=1 #去掉第一个路径,例如:/manager/user/login -转发到下游微服务-> /user/login- AddRequestHeader=X-Request-From, sl-express-gateway  #转发到下游微服务携带的请求头,增强安全性

自定义过滤器

在过滤器中主要实现以下几个功能:

  • 白名单放行
  • 请求头中的token是否有效
  • 权限是否匹配(校验角色)
  • 向下游微服务传递解析token的数据以及token值
/*** 管理端token校验的过滤器*/
@Component
public class ManagerTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {@Resourceprivate MyConfig myConfig;@Resourceprivate TokenCheckService tokenCheckService;@Value("${role.manager}")private List<Long> managerRoleIds; //获取配置文件中的管理员角色id@Overridepublic GatewayFilter apply(Object config) {return (exchange, chain) -> {//1. 校验请求路径,如果是白名单,直接放行String path = exchange.getRequest().getPath().toString();if (StrUtil.startWithAny(path, this.myConfig.getNoAuthPaths())) {//直接放行return chain.filter(exchange);}//2. 获取请求头中的token,进行校验,如果为空或校验失效,响应401String token = exchange.getRequest().getHeaders().getFirst(Constants.GATEWAY.AUTHORIZATION);if (StrUtil.isEmpty(token)) {//设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//校验tokenAuthUserInfoDTO authUserInfoDTO = null;try {authUserInfoDTO = this.tokenCheckService.parserToken(token);} catch (Exception e) {//token不可用,不做处理}if (ObjectUtil.isEmpty(authUserInfoDTO)) {//token不可用,设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//3. 校验权限,如果是非管理员不能登录AuthTemplate authTemplate = AuthTemplateFactory.get(token);//3.1 获取用户拥有的角色id列表List<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();//3.2 取交集,判断用户拥有的角色是否与预定的角色列表是否有交集Collection<Long> intersection = CollUtil.intersection(roleIds, this.managerRoleIds);if (CollUtil.isEmpty(intersection)) {//无交集,说明没有权限,设置响应状态码为400exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}//4. 校验通过,向下游传递用户信息和tokenexchange.getRequest().mutate().header(Constants.GATEWAY.USERINFO, JSONUtil.toJsonStr(authUserInfoDTO));exchange.getRequest().mutate().header(Constants.GATEWAY.TOKEN, token);//4.1 校验通过放行return chain.filter(exchange);};}}

代码优化

前面虽然已经实现了管理端的校验工作,同学们可以思考这样一个问题,如果实现司机端的校验,该怎么做呢?是不是意识到问题了?代码逻辑是不是很像?怎么办?没错,抽取共用代码!

优化一 

将校验逻辑抽取到独立的类中,这样在每个端的GatewayFilterFactory中就可以共用了。

package com.sl.gateway.filter;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.itheima.auth.factory.AuthTemplateFactory;
import com.itheima.auth.sdk.AuthTemplate;
import com.itheima.auth.sdk.dto.AuthUserInfoDTO;
import com.itheima.auth.sdk.service.TokenCheckService;
import com.sl.gateway.config.MyConfig;
import com.sl.transport.common.constant.Constants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;@Component
public class TokenGatewayFilter implements GatewayFilter {@Resourceprivate MyConfig myConfig;@Resourceprivate TokenCheckService tokenCheckService;@Value("${role.manager}")private List<Long> managerRoleIds; //获取配置文件中的管理员角色id@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1. 校验请求路径,如果是白名单,直接放行String path = exchange.getRequest().getPath().toString();if (StrUtil.startWithAny(path, this.myConfig.getNoAuthPaths())) {//直接放行return chain.filter(exchange);}//2. 获取请求头中的token,进行校验,如果为空或校验失效,响应401String token = exchange.getRequest().getHeaders().getFirst(Constants.GATEWAY.AUTHORIZATION);if (StrUtil.isEmpty(token)) {//设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//校验tokenAuthUserInfoDTO authUserInfoDTO = null;try {authUserInfoDTO = this.tokenCheckService.parserToken(token);} catch (Exception e) {//token不可用,不做处理}if (ObjectUtil.isEmpty(authUserInfoDTO)) {//token不可用,设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//3. 校验权限,如果是非管理员不能登录AuthTemplate authTemplate = AuthTemplateFactory.get(token);//3.1 获取用户拥有的角色id列表List<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();//3.2 取交集,判断用户拥有的角色是否与预定的角色列表是否有交集Collection<Long> intersection = CollUtil.intersection(roleIds, this.managerRoleIds);if (CollUtil.isEmpty(intersection)) {//无交集,说明没有权限,设置响应状态码为400exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}//4. 校验通过,向下游传递用户信息和tokenexchange.getRequest().mutate().header(Constants.GATEWAY.USERINFO, JSONUtil.toJsonStr(authUserInfoDTO));exchange.getRequest().mutate().header(Constants.GATEWAY.TOKEN, token);//4.1 校验通过放行return chain.filter(exchange);}
}

使用

package com.sl.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 管理端token校验的过滤器*/
@Component
public class ManagerTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {@Resourceprivate TokenGatewayFilter tokenGatewayFilter;@Overridepublic GatewayFilter apply(Object config) {return this.tokenGatewayFilter;}}

优化二

通过前面的优化一已经将过滤器抽取到一个独立的类中,这样就可以在多个过滤器工厂中通用了,但也是存在一些问题的,例如:

  • 不同的终端校验的角色id是不同的
  • 用户端是不需要校验角色的
  • 用户端校验token的逻辑与其他三端是不一样的
  • 用户端请求头中的token参数名与其他三端也不一样

基于这些问题,就能够意识到,单纯的抽取代码是不够的,需要进一步的优化。想一想,该怎么优化呢?

优化的思路就是,在TokenGatewayFilter中保留四端通用的逻辑,不同的逻辑抽取到接口中,由四端具体的实现。

package com.sl.gateway.filter;import com.itheima.auth.sdk.dto.AuthUserInfoDTO;
import com.sl.transport.common.constant.Constants;/*** 鉴权业务的回调,具体逻辑由 GatewayFilterFactory 具体完成*/
public interface AuthFilter {/*** 校验token** @param token 请求中的token* @return token中携带的数据*/AuthUserInfoDTO check(String token);/*** 鉴权** @param token        请求中的token* @param authUserInfo token中携带的数据* @param path         当前请求的路径* @return 是否通过*/Boolean auth(String token, AuthUserInfoDTO authUserInfo, String path);/*** 请求中携带token的名称** @return 头名称*/default String tokenHeaderName() {return Constants.GATEWAY.AUTHORIZATION;}}
package com.sl.gateway.filter;import cn.hutool.core.collection.CollUtil;
import com.itheima.auth.factory.AuthTemplateFactory;
import com.itheima.auth.sdk.AuthTemplate;
import com.itheima.auth.sdk.dto.AuthUserInfoDTO;
import com.itheima.auth.sdk.service.TokenCheckService;
import com.sl.gateway.config.MyConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;/*** 管理端token校验的过滤器*/
@Component
public class ManagerTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> implements AuthFilter {@Resourceprivate MyConfig myConfig;@Resourceprivate TokenCheckService tokenCheckService;@Value("${role.manager}")private List<Long> managerRoleIds; //获取配置文件中的管理员角色id@Overridepublic GatewayFilter apply(Object config) {//由于要传递当前对象,所以不能采用spring注入的方式,这里采用手动构造对象的方式传入return new TokenGatewayFilter(this.myConfig, this);}@Overridepublic AuthUserInfoDTO check(String token) {try {return this.tokenCheckService.parserToken(token);} catch (Exception e) {//token不可用,不做处理}return null;}@Overridepublic Boolean auth(String token, AuthUserInfoDTO authUserInfo, String path) {//校验权限,如果是非管理员不能登录AuthTemplate authTemplate = AuthTemplateFactory.get(token);//获取用户拥有的角色id列表List<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfo.getUserId()).getData();//取交集,判断用户拥有的角色是否与预定的角色列表是否有交集Collection<Long> intersection = CollUtil.intersection(roleIds, this.managerRoleIds);return CollUtil.isNotEmpty(intersection);}
}
package com.sl.gateway.filter;import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.itheima.auth.sdk.dto.AuthUserInfoDTO;
import com.sl.gateway.config.MyConfig;
import com.sl.transport.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Slf4j
public class TokenGatewayFilter implements GatewayFilter {private AuthFilter authFilter;private MyConfig myConfig;public TokenGatewayFilter(MyConfig myConfig, AuthFilter authFilter) {this.myConfig = myConfig;this.authFilter = authFilter;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1. 校验请求路径,如果是白名单,直接放行String path = exchange.getRequest().getPath().toString();if (StrUtil.startWithAny(path, this.myConfig.getNoAuthPaths())) {//直接放行return chain.filter(exchange);}//2. 获取请求头中的token,进行校验,如果为空或校验失效,响应401String token = exchange.getRequest().getHeaders().getFirst(this.authFilter.tokenHeaderName());if (StrUtil.isEmpty(token)) {//设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//校验tokenAuthUserInfoDTO authUserInfoDTO = null;try {authUserInfoDTO = this.authFilter.check(token);} catch (Exception e) {//token不可用,不做处理}if (ObjectUtil.isEmpty(authUserInfoDTO)) {//token不可用,设置响应状态为401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//拦截请求return exchange.getResponse().setComplete();}//3. 校验权限Boolean auth = false;try {auth = this.authFilter.auth(token, authUserInfoDTO, path);} catch (Exception e) {log.error("鉴权失败, token = {}", token, e);}if (!auth) {//没有权限,设置响应状态码为400exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}//4. 校验通过,向下游传递用户信息和tokenexchange.getRequest().mutate().header(Constants.GATEWAY.USERINFO, JSONUtil.toJsonStr(authUserInfoDTO));exchange.getRequest().mutate().header(Constants.GATEWAY.TOKEN, token);//4.1 校验通过放行return chain.filter(exchange);}
}

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

相关文章:

  • wordpress开发手册中文一键优化
  • 厦门模板网站建设杭州网站提升排名
  • 南昌做网站多少钱商丘网络推广哪家好
  • 淄博网站建设0533cl网站设计与建设的公司
  • 阜宁有做网站的吗军事网站大全军事网
  • 济宁网站建设的公司站内优化包括哪些
  • 网站域名到期了怎么办百度手机助手app免费下载
  • 有一个网站自己做链接获取朋友位置企业培训内容有哪些
  • 免费网站app哪个好百度推广登录平台客服
  • 做网站的搜索引擎郑州抖音seo
  • 官网网站模板朝阳区搜索优化seosem
  • 专做白酒的网站百度ai入口
  • 广州工作室做网站优化资源配置
  • 网站关键词优化快速排名seo互联网营销培训
  • 如果建设网站市场推广seo职位描述
  • 移动wordpress 到根目录新的seo网站优化排名 排名
  • 类似于wordpress的网站谷歌收录提交入口
  • 上虞市住房和城乡建设局网站网络营销专业学校排名
  • 网站建设启凡新网站应该怎么做seo
  • 宁波led网站建设微信小程序开发文档
  • 互联网装修公司品牌汕头seo按天付费
  • 网站介绍模版如何做营销推广
  • 网站建设流程知乎3小时百度收录新站方法
  • 类似微薄利网站怎么做优化关键词排名提升
  • ftp给网站做备份怎么买到精准客户的电话
  • 自己做网站需要做服务器长沙本地推广
  • 学校网站建设特色百度文库官网入口
  • 重庆企业网站排名优化社交媒体推广
  • 沈阳哪里做网站杭州seo营销公司
  • 做推广哪个食品网站好青岛网站建设推广公司