微服务和VUE入门教程(13): token验证-zuul拦截与验证

微服务和VUE入门教程(13): token验证-zuul拦截与验证

微服务和VUE入门教程(0): 着手搭建项目
微服务和VUE入门教程(1): 搭建前端登录界面
微服务和VUE入门教程(2): 注册中心
微服务和VUE入门教程(3): user微服务的搭建
微服务和VUE入门教程(4):网关zuul的搭建
微服务和VUE入门教程(5): 前后端交互
微服务和VUE入门教程(6):连接数据库-mybatis
微服务和VUE入门教程(7):配置中心-config
微服务和VUE入门教程(8):前端主页的编写
微服务和VUE入门教程(9): token验证-token后端生成以及前端获取
微服务和VUE入门教程(10): token验证-前端登录拦截以及token过期提醒
微服务和VUE入门教程(11): mybatis 动态查询
微服务和VUE入门教程(12):前端提示搜索框的实现
微服务和VUE入门教程(13): token验证-zuul拦截与验证
微服务和VUE入门教程(14): 热部署
微服务和VUE入门教程(15): 课堂小知识
微服务和VUE入门教程(16): zuul 熔断
微服务和VUE入门教程(17): VUE 响应拦截器
微服务和VUE入门教程(18): 前端接口模块化
微服务和VUE入门教程(19): VUE组件化–子组件向父组件通信
微服务和VUE入门教程(20): VUE组件化–父组件向子组件通信
微服务和VUE入门教程(21): springboot中定时器-Schedule
微服务和VUE入门教程(22): 页面长时间未操作自动退出登录
微服务和VUE入门教程(23): 微服务之间的调用
微服务和VUE入门教程(24): 微服务之断路器
微服务和VUE入门教程(25): 微服务之Hystrix-dashboard
微服务和VUE入门教程(26): 微服务之turbine
微服务和VUE入门教程(27):VUE前端工程打包

1. 前言

对于后端的一些接口,有时候,我们不希望没有登录的人员访问,或者说,不希望没经过授权的人员访问。因此,我们可以在zuul这里,加一个过滤器,来验证请求头里是否带有合格的token。如果带有合格的token,说明访问者是合法登录使用人员,如果没有token或者token不合格,则不让他访问接口。

2.前端编写

2.1 请求拦截器

在main.js代码中加入下面代码。拦截向后端发送的http请求,在请求头里面,加入token(Authorization)。

//请求拦截器
axios.interceptors.request.use(
  //请求头加入token
  config =>{
    if(localStorage.getItem('Authorization')){
      config.headers.Authorization = localStorage.getItem('Authorization');
    }
    console.log(config);
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

2.2 后端验证代码

为了验证,我们加的请求拦截器是否真的生效,真的把token值加入到请求头里。我们在后端尝试打印一下请求头。修改my-user的UserController.java文件

@RequestMapping(value = "/token/test", method = RequestMethod.GET)
public void testToken(@RequestHeader Map<String,Object> header){
    System.out.println(header);
}

通过@RequestHeader Map<String,Object> header 来获取请求头,并且打印出来。

2.3 前端请求

我们在学生信息管理页面新加一个按钮,来触发这个按钮。
在这里插入图片描述

<el-button type="primary" @click="testToken">测试token</el-button>
testToken(){
  this.$axios.get('/user/token/test');
},

2.4 验证

当我们触发这个接口按钮时,打开后端my-user的日志,不出问题的话,打印出了请求头。我们往后拉,其中有我们加入的authorization字段。证明我们成功在请求头中加入了token值。当然,可以删除main.js中的请求拦截代码,试试后端打印出来的请求头里还带不带token。
在这里插入图片描述

3. 后端zuul修改

新建filter和util文件,TokenUtil.java直接从my-user微服务中负责过来就好。
在这里插入图片描述

记得在pom文件中加入JWT依赖。

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
</dependency>

ZuulTokenFilter.java

package com.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.zuul.util.TokenUtil;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class ZuulTokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

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

    /**
     * 判断请求的接口是否需要验证token
     * 在这里,我们设定 /api/user/login,不需要验证token
     * 若不需要验证,返回false,
     * 需要验证,返回true
     *
     */
    @Override
    public boolean shouldFilter() {
        //1. 获取Zuul提供的请求上下文对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        // 获取request对象
        HttpServletRequest request = requestContext.getRequest();
        if("/api/user/login".equals(request.getRequestURI())){
            return false;
        }else if(request.getMethod().equals("OPTIONS")){
            return false;
        }else {
            return true;
        }
    }

    /**
     * 若shouldFilter返回true,则运行run方法,来验证token
     * */
    @Override
    public Object run() throws ZuulException {

        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        // 获取token值
        String token = request.getHeader("authorization");
        System.out.println(token);
        // 判断是否为空
        if(token == null || "".equals(token.trim())){
            //没有token,验证失败
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }else {
            try {
                //验证token是否合格
                boolean tokenVerify = TokenUtil.verify(token);
                //如果token合格,根据请求,寻找路由
                if(tokenVerify){
                    requestContext.setSendZuulResponse(true);
                }else {
                    requestContext.setSendZuulResponse(false);
                    requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                }
            }catch (Exception e){
                requestContext.setSendZuulResponse(false);
                requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            }
        }
        return null;
    }
}

4. 验证

重启zuul,访问后端的接口,如果不出问题的话,zuul控制台中可以打印出下面的日志来。
在这里插入图片描述

补:

TokenUtil.java

package com.zuul.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

public class TokenUtil {
    private static final long EXPIRE_TIME = 24*60*60*1000;  //有效时长
    private static final String TOKEN_SECRET = "ben";       // 秘钥

    /**
     * 签名 生成
     * @parm userName
     * */
    public static String sign(String userName){
        String token = null;
        try {
            Date expiresAt = new Date(System.currentTimeMillis()+EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0")
                    .withClaim("userName",userName)
                    .withExpiresAt(expiresAt)
                    //使用HMAC256算法加密
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        }catch (Exception e){
            e.printStackTrace();
        }
        return token;
    }

    /**
    * 签名验证
    * @param token
    * */
    public static boolean verify(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET))
                    .withIssuer("auth0").build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过");
            System.out.println("userName:"+jwt.getClaim("userName").asString());
            System.out.println("过期时间:"+jwt.getExpiresAt());
            return true;
        }catch (Exception e){
            return false;
        }
    }

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值