网站备案是一年一次吗成都餐饮设计工作室

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

网站备案是一年一次吗,成都餐饮设计工作室,抖音推广公司,贵阳企业网站制作springcloud-网关(gateway) 概述 \Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API#xff0c;并为其提供跨领域的关注#xff0c;如#xff1a;安全、监控/指标和容错 常用术语 Route#xff08;路由#xff09;: 网关的基本构件。它由一个ID、一个目的地…springcloud-网关(gateway) 概述 \Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API并为其提供跨领域的关注如安全、监控/指标和容错 常用术语 Route路由: 网关的基本构件。它由一个ID、一个目的地URI、一个谓词Predicate集合和一个过滤器Filter集合定义。如果集合谓词为真则路由被匹配。Predicate谓词: 这是一个 Java 8 Function Predicate。输入类型是 [Spring Framework ServerWebExchange]。这让你可以在HTTP请求中的任何内容上进行匹配比如header或查询参数。Filter过滤器: 这些是 [GatewayFilter] 的实例已经用特定工厂构建。在这里你可以在发送下游请求之前或之后修改请求和响应。 网关工作原理 客户端向 Spring Cloud Gateway 发出请求。如果Gateway处理程序映射确定一个请求与路由相匹配它将被发送到Gateway Web处理程序。这个处理程序通过一个特定于该请求的过滤器链来运行该请求。过滤器被分割的原因是过滤器可以在代理请求发送之前和之后运行逻辑。所有的 pre 前过滤器逻辑都被执行。然后发出代理请求。在代理请求发出后post 后过滤器逻辑被运行。 业务架构图 开发流程 引入依赖 gateway框架需要引入loadbalancer,否则在访问的时候会出现503异常。 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId /dependency dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId /dependencybootstrap.yml配置 配置nacos 如果不需要nacos的配置可以不引入nacos的config依赖 dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependencyspring:application:name: ssc-cloud-gatewaycloud:nacos:discovery:server-addr: 192.168.201.81:7777namespace: ssc-cloud-idgroup: DEVregister-enabled: true配置gateway spring:cloud:gateway:discovery:locator:enabled: trueroutes:- id : ssc-order-id #路由编号(自定义)

uri: https://www.bilibili.com/ #跳转地址(网页跳转)lb–负载调整微服务uri: lb://ssc-cloud-olderpredicates:- Path/ssc-older/** #url 的映射名称(让客户看到的)filters:- StripPrefix1- id: ssc-paycenter-id #路由编号(自定义)uri: lb://ssc-cloud-paycenterpredicates:- Path/ssc-pay/**filters:- StripPrefix1路由配置规则

序号名称解释1id⾃定义的路由 ID保持唯⼀2uri目标服务地址以lb:// 开头则表示要去向的微服务名称3predicates路由条件4Filter过滤器过滤器是路由转发请求时所经过的过滤逻辑可⽤于修改请求、响应内容。 predicates断言条件 Path 实例: - Path/ssc-older/ routes:- id : ssc-older-id uri: lb://ssc-cloud-olderpredicates:- Path/ssc-older/** 解释: 当请求的路径为ssc-older开头的时转发到ssc-cloud-older微服服务器上ssc-cloud-older是navcos中微服务注册的名称。 Before - Before2017-01-20T17:42:47.789-07:00[Asia/Shanghai] 在某个时间之前的请求才会被转发到 http://localhost:9001 服务器上 After - After2017-01-20T17:42:47.789- 07:00[Asia/Shanghai] 在某个时间之后的请求才会被转发 Between - Between2017-01-20T17:42:47.789-07:00[Asia/Shanghai], 2017-01- 21T17:42:47.789-07:00[Asia/Shanghai] 在某个时间段之间的才会被转发 Cookie - CookiesesionId,ssc-test 名为ss-old的表单或者满⾜正则old的表单才会被匹配到 进⾏请求转发 routes:- id : ssc-older-id uri: lb://ssc-cloud-olderpredicates:- CookiesesionId,ssc-test Header - HeaderX-Request-Id 携带参数X-Request-Id的请求头才会匹配 Host - Hostwww.ssc.older.com 当主机名为www.ssc.older.com的时候直接转发到指定服务器。 Method - MethodGET 只有GET⽅法才会匹配转发请求还可以限定POST、PUT等。 routes:- id : ssc-older-id uri: lb://ssc-cloud-olderpredicates:- MethodGET,POST 过滤器规则 过滤规则实例说明PrefixPath- PrefixPath/app在请求路径前加上appPrefixPath- PrefixPath/app在请求路径前加上appSetPathSetPath/app/{path}通过模板设置路径转发的规则时会在路径前增加 app{path}表示原请求路径RedirectTo重定向RemoveRequestHea去掉某个请求头信息\1. PrefixPathStripPrefixPath/ssc-pay/去掉ssc-pay才是真实路径 网关的案例 使用网关进行用户鉴权过滤。 鉴权微服务 api模块 api模块为外界提供接口(openfeign调用),为网关调用需要基于reactor开发。 pom ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.wnhz.ssc.cloud.authority/groupIdartifactIdssc-cloud-authority/artifactIdversion0.0.1-SNAPSHOT/version/parentgroupIdcom.wnhz.ssc.cloud.authority.api/groupIdartifactIdssc-cloud-authority-api/artifactIddependenciesdependencygroupIdcom.playtika.reactivefeign/groupIdartifactIdfeign-reactor-webclient/artifactIdversion3.0.3/version/dependencydependencygroupIdcom.playtika.reactivefeign/groupIdartifactIdfeign-reactor-cloud/artifactIdversion3.0.3/version/dependencydependencygroupIdcom.playtika.reactivefeign/groupIdartifactIdfeign-reactor-spring-configuration/artifactIdversion3.0.3/version/dependency/dependencies /projectopenfeign接口 ReactiveFeignClient(value ssc-cloud-authority,url http://localhost:12121) public interface IAuthorityFeign {GetMapping(/api/authority/login)MonoHttpResp login(RequestParam(username) String username,RequestParam(password) String password);PostMapping(/api/authority/verifyToken)MonoHttpResp verifyToken(String token); }业务接口(sevice) pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.wnhz.ssc.cloud.authority/groupIdartifactIdssc-cloud-authority/artifactIdversion0.0.1-SNAPSHOT/version/parentgroupIdcom.wnhz.ssc.cloud.authority.service/groupIdartifactIdssc-cloud-authority-service/artifactIddependenciesdependencygroupIdcom.wnhz.ssc.cloud.springcloud/groupIdartifactIdssc-cloud-springcloud/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-openapi2-spring-boot-starter/artifactId/dependencydependencygroupIdcom.wnhz.ssc.cloud/groupIdartifactIdssc-cloud-tools/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdcom.wnhz.ssc.cloud/groupIdartifactIdssc-cloud-ssm/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency/dependencies /project配置 bootstrap.yml spring:cloud:nacos:config:server-addr: \({spring.cloud.nacos.discovery.server-addr}namespace: \){spring.cloud.nacos.discovery.namespace}file-extension: yamlextension-configs:- data-id: db_ssc.yamlgroup: DEVrefresh: true- data-id: redis.yamlgroup: DEVrefresh: truediscovery:server-addr: 192.168.201.107namespace: ssc-cloud-idgroup: DEVapplication:name: ssc-cloud-authorityapplication application-dev.yml server:port: 12121 knife4j:enable: true logging:level:com.wnhz: debugapplication.yml spring:profiles:active: dev启动类 EnableDiscoveryClient SpringBootApplication public class AuthorityApp {public static void main(String[] args) {SpringApplication.run(AuthorityApp.class);} }dao Mapper public interface ILoginDao extends BaseMapperLogin { }异常 /* 鉴权异常/ public class AuthorityException extends RuntimeException{public AuthorityException(String message) {super(message);} }/** 用户名或密码错误异常/ public class BadCredentialsException extends AuthorityException{public BadCredentialsException(String message) {super(message);} }service 接口 public interface ILoginService {Login loginCheck(String username, String password);ListLogin findByUsername(String username); }实现类 package com.wnhz.ssc.cloud.authority.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wnhz.ssc.cloud.authority.dao.ILoginDao; import com.wnhz.ssc.cloud.authority.exception.BadCredentialsException; import com.wnhz.ssc.cloud.authority.exception.UsernameEmptyException; import com.wnhz.ssc.cloud.authority.exception.UsernameNotFoundException; import com.wnhz.ssc.cloud.authority.service.ILoginService; import com.wnhz.ssc.domain.entity.po.Login; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils;import java.util.List; import java.util.Objects;Service public class LoginServiceImpl implements ILoginService {Autowiredprivate ILoginDao loginDao;Overridepublic Login loginCheck(String username, String password) {if (!StringUtils.hasText(username)) throw new UsernameEmptyException(用户名为空异常);LambdaQueryWrapperLogin lambdaQueryWrapper new LambdaQueryWrapper();lambdaQueryWrapper.eq(Login::getUsername, username);ListLogin logins findByUsername(username);Login login logins.stream().filter(lg - username.equals(lg.getUsername())).findFirst().get();if (Objects.isNull(login)) throw new BadCredentialsException(用户名|密码错误);return login;}/** 判读用户名是否存在* param username 用户名* return 所有查询服务用户名的用户集合/Overridepublic ListLogin findByUsername(String username) {ListLogin logins loginDao.selectList(new LambdaQueryWrapperLogin().eq(Login::getUsername, username));if (Objects.isNull(logins) || logins.isEmpty()) throw new UsernameNotFoundException(用户名不存在异常);return logins;} }controller package com.wnhz.ssc.cloud.authority.controller;import com.wnhz.ssc.cloud.authority.service.ILoginService; import com.wnhz.ssc.cloud.tools.exception.jwt.JwtException; import com.wnhz.ssc.cloud.tools.exception.jwt.JwtExpiredException; import com.wnhz.ssc.cloud.tools.jwt.JwtUtil; import com.wnhz.ssc.common.result.HttpResp; import com.wnhz.ssc.domain.entity.po.Login; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono;import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit;Api(tags 鉴权模块api) RestController RequestMapping(/api/authority) Slf4j public class AuthorityController {Autowiredprivate ILoginService loginService;Autowiredprivate StringRedisTemplate stringRedisTemplate;private final String REDIS_PREFIXtoken:;/** 用户登录** param username* param password* return*/ApiOperation(value login, notes 用户登录验证)GetMapping(/login)public HttpResp login(String username, String password) {try {Login login loginService.loginCheck(username, password);log.debug(用户名登录成功:{},login);MapString, Object map new HashMap();map.put(username, username);String token JwtUtil.getInstance().creatToken(map, 1000 * 30, login.getSign());stringRedisTemplate.opsForValue().set(REDIS_PREFIXtoken, login.getSign(),10, TimeUnit.MINUTES);log.debug(token产生成功并存入redis中:{},token);return HttpResp.success(new String[]{ssc_login_token, token});} catch (Exception e) {return HttpResp.failed(e.getMessage());}}/*** 验证token** param token* return*/ApiOperation(value verifyToken, notes token验证)GetMapping(/verifyToken)public MonoHttpResp verifyToken(String token) {String sign stringRedisTemplate.opsForValue().get(REDIS_PREFIXtoken);log.debug(从redis中获取token的值: {}, sign);if (Objects.isNull(sign)) {return Mono.just(HttpResp.failed(token不存在));}try {JwtUtil.getInstance().verifyToken(token, sign);return Mono.just(HttpResp.success(token验证成功));} catch (JwtExpiredException e) {//token已过期,判断是否续期return refreshToken(token, sign);} catch (JwtException e) {return Mono.just(HttpResp.failed(e.getMessage()));}}private MonoHttpResp refreshToken(String originalToken, String sign) {Long expireLeftTime stringRedisTemplate.getExpire(REDIS_PREFIXoriginalToken);log.debug(redis中token剩余时间:{}, expireLeftTime);if (expireLeftTime 0) {//token续期String newToken JwtUtil.getInstance().cloneToken(originalToken, expireLeftTime);stringRedisTemplate.delete(REDIS_PREFIXoriginalToken);stringRedisTemplate.opsForValue().set(REDIS_PREFIXnewToken, sign);log.debug(新token产生成功续期完成token {},newToken);return Mono.just(HttpResp.success(new String[]{ssc_login_token, newToken}));} //token已经过期redis也过期return Mono.just(HttpResp.failed(token已经过期));} }全局网关 负责对鉴权控制 pom ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdwnhz-ssc-cloud/artifactIdgroupIdcom.wnhz.ssc.cloud/groupIdversion0.0.1-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersiongroupIdcom.wnhz.ssc.cloud.gateway/groupIdartifactIdssc-cloud-gateway/artifactIddependenciesdependencygroupIdcom.wnhz.ssc.cloud.springcloud/groupIdartifactIdssc-cloud-springcloud/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdcom.wnhz.ssc.cloud.common/groupIdartifactIdssc-cloud-common/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependencydependencygroupIdcom.playtika.reactivefeign/groupIdartifactIdfeign-reactor-spring-configuration/artifactIdversion3.0.3/versionscopecompile/scope/dependencydependencygroupIdcom.wnhz.ssc.cloud.authority.api/groupIdartifactIdssc-cloud-authority-api/artifactIdversion0.0.1-SNAPSHOT/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationoutputDirectory../out/outputDirectory/configuration/plugin/plugins/build /project配置 bootstrap.yml spring:main:web-application-type: reactiveapplication:name: ssc-cloud-gatewaycloud:nacos:discovery:server-addr: 192.168.201.81:7777namespace: ssc-cloud-idgroup: DEVregister-enabled: trueconfig:enabled: offgateway:discovery:locator:enabled: trueroutes:- id : ssc-order-id #路由编号(自定义)

uri: https://www.bilibili.com/ #跳转地址(网页跳转)lb–负载调整微服务uri: lb://ssc-cloud-olderpredicates:- Path/ssc-older/** #url 的映射名称(让客户看到的)filters:- StripPrefix1- id: ssc-paycenter-id #路由编号(自定义)uri: lb://ssc-cloud-paycenterpredicates:- Path/ssc-pay/filters:- StripPrefix1- id: ssc-authority-id #路由编号(自定义)uri: lb://ssc-cloud-authoritypredicates:- Path/ssc-auth/filters:- StripPrefix1全局过滤器

package com.wnhz.ssc.cloud.gateway.filter;import com.fasterxml.jackson.databind.ObjectMapper; import com.wnhz.ssc.cloud.authority.feign.IAuthorityFeign; import com.wnhz.ssc.common.result.HttpResp; import com.wnhz.ssc.common.result.RespCode; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter; import org.springframework.context.annotation.Lazy; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; 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.web.server.ServerWebExchange; import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects;Component Slf4j public class SscGlobalGatewayFilter implements GlobalFilter, Ordered {LazyAutowiredprivate IAuthorityFeign authorityFeign;private final String LOGIN_TOKENssc_login_token;SneakyThrowsOverridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request exchange.getRequest();ServerHttpResponse response exchange.getResponse();log.debug(我进入过滤中…..);ObjectMapper objectMapper new ObjectMapper();DataBuffer dataBuffer null;String requestURI request.getURI().getPath() ;log.debug(请求uri:{},requestURI);if(requestURI.endsWith(/authority/login)){//客户访问登录业务直接跳转验证return chain.filter(exchange);}//1. Token不存在客户未登录状态访问系统if(!isLogin(request)) {//如果客户没有登录log.debug(客户还没有登录,重定向到登录(baidu)页面);String redirectUrl https://www.baidu.com;log.debug(将客户请求重定向到指定页面: {}, redirectUrl);response.getHeaders().set(HttpHeaders.LOCATION, redirectUrl);//303状态码表示由于请求对应的资源存在着另一个URI应使用GET方法定向获取请求的资源response.setStatusCode(HttpStatus.SEE_OTHER);response.getHeaders().add(Content-Type, text/plain;charsetUTF-8);return response.setComplete();}//2. token存在调用验证微服务验证token是否有效String token getToken(request);HttpResp block authorityFeign.verifyToken(token).block();if(block.getCode() RespCode.FAILED.getCode()){ //token验证失败response.getHeaders().add(Content-Type, application/json;charsetUTF-8);dataBuffer response.bufferFactory().wrap(objectMapper.writeValueAsString(block).getBytes(StandardCharsets.UTF_8));return response.writeWith(Mono.just(dataBuffer));}return chain.filter(exchange);}Overridepublic int getOrder() {return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;}/*** 客户未登录没有token* param request* return/private boolean isLogin(ServerHttpRequest request){HttpHeaders headers request.getHeaders();log.debug(header {}, headers);ListString loginToken headers.get(LOGIN_TOKEN);if(Objects.nonNull(loginToken)){return true;}return false;}/** 从请求中获取token* param request*/private String getToken(ServerHttpRequest request){HttpHeaders headers request.getHeaders();log.debug(header {}, headers);ListString tokens headers.get(LOGIN_TOKEN);String token tokens.get(0);return token;} } 启动类 package com.wnhz.ssc.cloud.gateway;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import reactivefeign.spring.config.EnableReactiveFeignClients;SpringBootApplication EnableDiscoveryClient EnableReactiveFeignClients(basePackages com.wnhz.ssc.cloud.authority.feign) public class GatewayApp {public static void main(String[] args) {SpringApplication.run(GatewayApp.class);} } HttpHeaders headers request.getHeaders();log.debug(header {}, headers);ListString tokens headers.get(LOGIN_TOKEN);String token tokens.get(0);return token; }} ### 启动类java package com.wnhz.ssc.cloud.gateway;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import reactivefeign.spring.config.EnableReactiveFeignClients;SpringBootApplication EnableDiscoveryClient EnableReactiveFeignClients(basePackages com.wnhz.ssc.cloud.authority.feign) public class GatewayApp {public static void main(String[] args) {SpringApplication.run(GatewayApp.class);} }