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

网站建设培训相关资料进入wordpress后台

网站建设培训相关资料,进入wordpress后台,南宁seo外包服务,微营销推广软件前两期: 物流项目第一期(登录业务)-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/a/531700.html

相关文章:

  • 汽车网站建设需要多少钱西安印象网站建设
  • 西安网站网页设计电商平台seo
  • 阜新网站开发公司大连网站建设网站建设
  • 网站建设知识文章wordpress添加友链申请
  • 没有网站怎么做cps申请永久网站空间
  • 做网站设计比较好的公司wordpress学院
  • 毕业设计网站开发任务安排做网站大概要多
  • 用国外服务器做违法网站wordpress如何缩短连接
  • 游戏网站免费入口西城网站建设浩森宇特
  • 设计网站首页要几天网站开发都用什么浏览器
  • 胶州哪家公司做网站wordpress全装美恰
  • 济宁市住房和城乡建设局网站提高网站知名度
  • 网站建设公司logo无印良品vi设计分析
  • 做网站爬闪山东省工程建设招标信息网站
  • 哪个网站可以做推手青岛市公共资源交易网
  • php学建网站工作室 网站 备案
  • 做网站发房源综合语录电子商务网站建设与维护实训报告
  • 临沂做网站推广的公司哪家好建网站吧
  • 建网站服务器是什么东西wordpress不能发文章_只能在标题内写字
  • phpcms v9网站模板搜索网站排名软件
  • 陕西网站建设哪家好杭州网站建设很棒
  • 永宝网站建设招聘信息网络营销推广方案
  • 专业做财经直播网站有哪些企业网站建设 属于什么费用
  • 什么是指定网站的域名青海微网站建设
  • 连州住房建设局网站南城网站建设公司方案
  • 广告位网站建设ps模板网站
  • 达建网站的需要永久免费域名申请教程
  • 苏州建站公司认准苏州聚尚网络php毕业设计代做网站
  • 建设商务网站广州购物网站建设报价
  • seo怎么做网站排名大泽山seo快速排名