栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Cloud Zuul网关配置启动,拦截器,JWT如何实现在网关中拦截没有token的请求,笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Cloud Zuul网关配置启动,拦截器,JWT如何实现在网关中拦截没有token的请求,笔记

Zuul一个网关插件
作用:

  • 每个服务都可以被外界单独访问,所以我们就需要把所有的服务端口给隐藏,对外只提供一个统一访问的地址,
  • 对内代理每个服务的路由,派发给某些服务

怎么使用Zuul 先导入zuul的依赖:

        
            org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        

导入zuul的依赖后
我们在配置文件中进行相关配置
启动类添加注解

  • @EnableZuulProxy声明启用zuul代理
  • @EnableEurekaClient开启服务注册发现功能。

  • 在把USER服务添加到网关里面
  • http://localhost:19000/user/chaxun
  • 然后我们就可以通过网关的端口来对用户服务进行访问了
Zuul的过滤器

ZuulFilter

  • 那么我们怎么使用Zuul给我们提供的过滤器呢?
  • 写一个子类过滤器来继承ZuulFilter给我们提供的过滤方法和相关配置
package com.example.s83790cloudzuul.filter;

import com.netflix.zuul.*;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;


@Component
public class CustomZuulFilter extends ZuulFilter
{

    @Override
    public String filterType()
    {
         //过滤器的类型
        // 1)pre
        //可以在请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程。
        //2)route
        //在路由请求时被调用。适用于灰度发布场景,在将要路由的时候可以做一些自定义的逻辑。
        //3)post
        //在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头,记录响应日志等应用场景。
        //4)error
        //处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息。
        return "pre";
    }

    @Override
    public int filterOrder()
    {
        //此过滤器的优先级,0的优先级是最高,其他逐渐次知
        return 0;
    }

    @Override
    public boolean shouldFilter()

    {
        //是否开启过滤,开启true 关闭 false
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();//获取当此被拦截的请求
        String requestURI = String.valueOf(request.getRequestURL());
        String http ="http://127.0.0.1:19000/user/lhj";
        return !(requestURI.equals(http));
    }

    @Override
    public Object run() throws ZuulException
    {
        //获取当前应用请求的上下文
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();//获取当此被拦截的请求
        String name = request.getParameter("username");//获取请求中获取某个参数
        if (name == null || "".equals(name))
        {
            //阻止请求进入后续处理
            requestContext.setSendZuulResponse(false);//过滤该请求不对其进行路由
            requestContext.setResponseStatusCode(404);//返回错误码
        }
        return null;
    }


}

JWT

JWT:令牌权限控制

我们为什么要使用JWT?

在原来我们的服务中,前端接收到用户的请求就需要跨域回后端,假如我需要登录,那么我们的流程就是
登录界面 —— 发生请求 > 后端controller ——分配业务> service —— 请求Dao数据> ——>dao
Dao从数据库查完数据之后还要原来返回到前端,并且将用户数据保存在当前会话中session中,这样一来要是访问的人少还好说,但是如果你访问的人多了起来服务器是抗不住的几千万个session或者几亿个

所以就有了JWT JWT产生一个token,在你访问其他页面时会检查你的令牌是不是为空,又或者是不是有效,如果为空或无效的话就不让你访问。
这样一来总是判断你的用户是否登录,而且也不用存到session里面浪费服务器资源,

package com.example.s83790authentication.controller;

import com.google.common.collect.Maps;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.Map;


public class JWTUtils {
    static Map map = Maps.newConcurrentMap();//token里面带的数据

    static String miYao = "LHJ_HEN_SHUAIZDHSZDHS";//进行数字签名的私钥

	//生成令牌的方法
    public static String getToken(String username,String password) {
        map.put("username", username);//用户名
        map.put("password",password);//密码
        //生成令牌
        return   Jwts.builder()
                .setId("tokenid")//设置令牌ID
                .setSubject("塞杰博")//设置令牌所属于
                .setClaims(map)//设置令牌保存的数据
                .setExpiration(new Date(System.currentTimeMillis()+10*1000))//令牌过期时间
                .setIssuedAt(new Date(System.currentTimeMillis()))//令牌生效时间
                .signWith(SignatureAlgorithm.HS256, miYao)//头部信息 第一个参数为加密方式为哈希256,第二个参数是更具密钥加密
                .compact();//生成令牌
    }

    public static boolean get(String a)//解析令牌内容
    {
        try {
            Jws claimsJws =Jwts.parser().setSigningKey(miYao).parseClaimsJws(a);//把令牌解析成>
            Claims  claims = claimsJws.getBody();
            long guoqi = claims.getExpiration().getTime();//得到令牌的过期时间
            long dangq = System.currentTimeMillis();//得到当前时间
            System.out.println("过期时间:"+guoqi);
            System.out.println("当前时间:"+dangq);

            if (guoqi-dangq>0)
            {
                System.out.println("没过期");
                return true;
            }
        }catch (Exception e)
        {
            System.out.println("过期");
            return false;
        }

        return true;
    }


}

zuul过滤器获取token

package com.example.s83790cloudzuul.filter;

import cn.dev33.satoken.stp.StpUtil;
import com.netflix.zuul.*;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;


@Component
public class CustomZuulFilter extends ZuulFilter
{
    @Autowired
    RestTemplate restTemplate;


    @Override
    public String filterType()
    {
        //过滤器的类型
        // 1)pre
        //可以在请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程。
        //2)route
        //在路由请求时被调用。适用于灰度发布场景,在将要路由的时候可以做一些自定义的逻辑。
        //3)post
        //在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头,记录响应日志等应用场景。
        //4)error
        //处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息。
        return "pre";
    }

    @Override
    public int filterOrder()
    {
        //此过滤器的优先级,0的优先级是最高,其他逐渐次知
        return 0;
    }

    @Override
    public boolean shouldFilter()

    {
        //是否开启过滤,开启true 关闭 false
       
        return true;
    }

    @Override
    public Object run() throws ZuulException
    {
        //获取当前应用请求的上下文
        RequestContext requestContext = RequestContext.getCurrentContext();
        String token = StpUtil.getTokenValue();
        System.out.println("token:"+token);
        if (StpUtil.getLoginIdByToken(token)==null)
        {
            requestContext.setSendZuulResponse(false);// 过滤该请求,不对其进行路由
            requestContext.setResponseStatusCode(505);
            requestContext.setResponseBody("请先登录后操作......");
        }else
        {
            if (restTemplate.getForObject("http://AUTHSERVICE/tokenTimeout",String.class).equals("过期"))//远程调用用户服务里面的token方法解析这个token是不是过期
            {
                System.out.println("过期");
                requestContext.setSendZuulResponse(false);// 过滤该请求,不对其进行路由
                requestContext.setResponseStatusCode(506);// 返回错误码
                requestContext.setResponseBody("令牌过期......");// 返回错误内容
            }
        }

        return null;
    }


}

zuul调用其他服务解析token的方法

 @RequestMapping("/tokenTimeout")
    public String getJwt()
    {
        System.out.println("token:"+StpUtil.getTokenValue());
        return StpUtil.getTokenActivityTimeout()==-2L? "过期":"没过期";
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/583336.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号