在微服務的架構中,有一個東西非常重要,那就是鑑權,先簡單介紹一下這個鑑權是什麼。
我們對外提供接口,那並不代表着每個人都有權力訪問接口,此時就需要對接口進行限制訪問。一般的做法就是給訪問接口的人發放一個令牌token,一般情況下把token放在header上面,每次請求的時候,都帶着這個token。
在本章節中,我們模擬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的實驗
不帶token
當我們不帶token的時候,會提示我們的請求沒有token,不給我們訪問接口,實驗成功。
帶錯誤token的實驗
帶錯誤token
當我們訪問帶上錯誤的token的時候,會提示token錯誤,不能訪問接口,實驗成功。
帶正確token的實驗
帶上正確的token
此時我們帶上了正確的token,訪問是成功的。
總結:在本次的鑑權中,只是模擬了token的鑑權,本質上原理如此,生產中,會結合redis,把token放在redis上面,做超時處理,同時還會對token做更加複雜的正確與否處理。
最後,謝謝觀賞,覺得好的話,點個贊,有什麼問題可以留言溝通,麼麼噠。