微服务网关实战05-网关鉴权

在微服务的架构中,有一个东西非常重要,那就是鉴权,先简单介绍一下这个鉴权是什么。

我们对外提供接口,那并不代表着每个人都有权力访问接口,此时就需要对接口进行限制访问。一般的做法就是给访问接口的人发放一个令牌token,一般情况下把token放在header上面,每次请求的时候,都带着这个token。

微服务网关实战05-网关鉴权_第1张图片

 

在本章节中,我们模拟token请求及校验,在filter包中添加鉴权类,如下:

SecurityFiltter鉴权类

/**
 * All rights Reserved, Designed By OprCalf
 * Copyright:    Copyright(C) 2016-2020
 * Company       LengYin Ltd.
 */

package com.platform.gateway.common.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.platform.gateway.common.utils.MsgUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @projectName:  platform-gateway-demo
 * @package:      com.platform.gateway.common.filters
 * @className:    SecurityFiltter.java
 * @description:  鉴权过滤
 * @author:       OprCalf
 * @date:         2020年3月9日
 */
@Slf4j
@Component
public class SecurityFiltter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return Integer.MIN_VALUE + 3;
    }

    @Override
    public boolean shouldFilter() {
        final RequestContext ctx = RequestContext.getCurrentContext();
        // 当发生异常的时候,不是进行取值
        if (ctx.getThrowable() != null) {
            log.error("{}", ctx.getThrowable().fillInStackTrace());
            if (ctx.sendZuulResponse()) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    @Override
    public Object run() throws ZuulException {
        final RequestContext ctx = RequestContext.getCurrentContext();
        final HttpServletRequest request = ctx.getRequest();
        final HttpServletResponse response = ctx.getResponse();
        try {
            final String token = request.getHeader("access_token");
            if (Strings.isNullOrEmpty(token)) {
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
                response.setContentType("application/json;charset=UTF-8");
                response.getOutputStream().write(MsgUtils.buildFailureMsg("当前请求没有token").toString().getBytes("utf-8"));
            } else {
                final String tokenValue = "nc3yb4x9n24nty23nu034bry9cy359-x23n4-x";
                if (!tokenValue.equals(token)) {
                    ctx.setSendZuulResponse(false);
                    ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
                    response.setContentType("application/json;charset=UTF-8");
                    response.getOutputStream()
                            .write(MsgUtils.buildFailureMsg("当前token不正确").toString().getBytes("utf-8"));
                }
            }
            return null;
        }
        catch (final Exception e) {
            log.error("{}", e.fillInStackTrace());
        }
        return null;
    }

}

这样就完成了简单的token校验,接下来我们来进行实验

不带token的实验

微服务网关实战05-网关鉴权_第2张图片

不带token

当我们不带token的时候,会提示我们的请求没有token,不给我们访问接口,实验成功。

带错误token的实验

微服务网关实战05-网关鉴权_第3张图片

带错误token

当我们访问带上错误的token的时候,会提示token错误,不能访问接口,实验成功。

带正确token的实验

微服务网关实战05-网关鉴权_第4张图片

带上正确的token

此时我们带上了正确的token,访问是成功的。

总结:在本次的鉴权中,只是模拟了token的鉴权,本质上原理如此,生产中,会结合redis,把token放在redis上面,做超时处理,同时还会对token做更加复杂的正确与否处理。

最后,谢谢观赏,觉得好的话,点个赞,有什么问题可以留言沟通,么么哒。

你可能感兴趣的:(微服务网关)