SpringBoot+SpringCloud搭建Zuul网关

本文介绍了一种使用Zuul网关实现前后端分离的方案,详细讲解了如何配置网关转发请求到不同微服务及后台权限验证的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
如图所示,
1、我的用户登录之后,并不是直接访问微服务,是由网关去分发跳转指定的微服务【用户登陆我没有做认证,只要你登陆了,我就把头信息原封不动的传下去】

2、后台人员登陆怎么办呢,我在ManagerFilter拦截器里面去判断他是不是管理员,如果是,头信息原封不动的往下传,如果不是,判处异常权限不足,往下的步骤直接不执行
废话不多说,上代码
在这里插入图片描述

前台网关

pom依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>com.pure</groupId>
            <artifactId>pure_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

application.yml

server:
  port: 9012
spring:
  application:
    name: pure-web #指定服务名
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7878/eureka/
  instance:
    prefer-ip-address: true #是为了在线上时模块之间能够跨域访问
zuul:
  routes:
    pure-user: #用户
      path: /user/**  #配置请求URL的请求规则
      serviceId: pure-user #指定Eureka注册中心中的服务id
    pure-Article:  #文章
      path: /article/** #配置请求URL的请求规则
      serviceId: pure-Article #指定Eureka注册中心中的服务id
    pure-base: #基础
      path: /base/** #带有这个路径,自动往pure-base这里跳转,【zuul网关操作】
      serviceId: pure-base #指定Eureka注册中心中的服务id

启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableEurekaClient
@EnableZuulProxy
public class WebApplication {
    public static void main ( String[] args ) {
        SpringApplication.run ( WebApplication.class,args );
    }
}

拦截器

//web的Zuul拦截器只要转发头信息就可以,这是用户的操作,不需要验证是否管理员权限
@Component
public class WebFilter extends ZuulFilter {
    @Override
    public String filterType () {
        return "pre";
    }

    @Override
    public int filterOrder () {
        return 0;
    }

    @Override
    public boolean shouldFilter () {
        return true;
    }

    @Override
    public Object run () throws ZuulException {
        System.out.println ( "经过前台Zuul过滤器" );
        //先得到Request上下文
        RequestContext currentContext = RequestContext.getCurrentContext ( );

        //得到Request域
        HttpServletRequest request = currentContext.getRequest ( );

        //得到头信息
        String header = request.getHeader ( "Authorization" );

        //判断是否有头信息
        if (StringUtils.isNotEmpty ( header ) && StringUtils.isNotEmpty ( " " )) {
            //把头信息继续往下传
            currentContext.addZuulRequestHeader ( "Authorization",header );
        }
        return null;
    }
}

后台网关

pom依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>com.pure</groupId>
            <artifactId>pure_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

application.yml

server:
  port: 9012
spring:
  application:
    name: pure-web #指定服务名
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7878/eureka/
  instance:
    prefer-ip-address: true #是为了在线上时模块之间能够跨域访问
zuul:
  routes:
    pure-user: #用户
      path: /user/**  #配置请求URL的请求规则
      serviceId: pure-user #指定Eureka注册中心中的服务id
    pure-Article:  #文章
      path: /article/** #配置请求URL的请求规则
      serviceId: pure-Article #指定Eureka注册中心中的服务id
    pure-base: #基础
      path: /base/** #带有这个路径,自动往pure-base这里跳转,【zuul网关操作】
      serviceId: pure-base #指定Eureka注册中心中的服务id

启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableEurekaClient
@EnableZuulProxy
public class ManagerApplication {
    public static void main ( String[] args ) {
        SpringApplication.run ( ManagerApplication.class,args );
    }

    @Bean
    public JwtUtil jwtUtil(){
        return  new JwtUtil ();
    }
}

后台拦截器

/**
 * @author 刘乐锋
 * @create 2021/3/18 15:20
 */
//Manager的Zuul拦截器,要执行转发头信息,并且要验证权限
@Component
public class ManagerFilter extends ZuulFilter {
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public String filterType () {
        //pre表示执行之前过滤
        //post表示执行之后进行过滤
        return "pre";
    }

    @Override
    public int filterOrder () {//排序,0表示优先执行
        return 0;
    }

    @Override
    public boolean shouldFilter () {
        return true;
    }

    @Override
    public Object run () throws ZuulException {
        System.out.println ( "经过后台zuul过滤器" );
        //先得到Request上下文
        RequestContext requestContext = RequestContext.getCurrentContext ( );
        HttpServletRequest request = requestContext.getRequest ( ); //获取request

        /**
         * 在转发的时候,内部有一个OPTIONS方法,这个方法负责找具体的请分支跳转
         * 任何经过网关的请求都是两次,分发路径的请求,第一次没有携带Authorization
         */
        if (request.getMethod ( ).equals ( "OPTIONS" )) {
            return null;
        }

        /**
         * 登陆放行
         */
        //当前这个单词在路径中出现的位置,出现在哪个位置,就返回哪个位置下标,如果没有就是等于 0,有就是大于0即登陆请求
        if (request.getRequestURI ( ).indexOf ( "admin/login" ) > 0) {
            return null;

        }
        //得到头信息
        String header = request.getHeader ( "Authorization" );
        if (StringUtils.isNotEmpty ( header ) && StringUtils.isNotEmpty ( " " )) {
            if (header.startsWith ( "Bearer" )) {
                String token = header.substring ( 7 );
                try {
                    Claims claims = jwtUtil.parseJWT ( token );
                    String roles = (String) claims.get ( "roles" );
                    if (roles.equals ( "admin" )) {
                        //转发头信息,并且放行
                        requestContext.addZuulRequestHeader ( "Authorization",header );
                        System.out.println ( "token验证通过,添加了头信息"+header );
                        return null;  //  return null就是转发
                    }
                } catch (Exception e) {
                    requestContext.setSendZuulResponse ( false ); //终止运行
                }
            }
        }
        requestContext.setSendZuulResponse ( false ); //终止运行
        requestContext.setResponseStatusCode ( 403 ); //权限不足
        requestContext.setResponseBody ( "权限不足" );
        requestContext.getResponse ( ).setContentType ( "text/html;charset=utf-8" ); //这不是JSON如果是json【application/json】
        return null;
    }
}

技术有待欠缺,请指导!!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值