1.API接口设计规范
2.安全性设计
a.白名单限制
仅接受特定系统的请求响应,调用方的IP地址需要在本系统中报备,否则无法调用
b.合法身份合法性验证
Basic Authentication :这种方式是直接将用户名和密码放到Header中,使用 Authorization: Basic Zm9vOmJhcg== ,使用最简单但是最不安全。
TOKEN认证:这种方式也是再HTTP头中,使用 Authorization: Bearer ,使用最广泛的TOKEN是JWT,通过签名过的TOKEN。
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
类似JWT,只是用户登录成功后将token信息是保存在redis中,可以设置token有效期,或主动将token失效等,并返回给用户。
其他认证接口时必须在header中输入token信息,并验证。
@Aspect
@Component
public class SecurityAspect {
@Resource(name = "redisTokenManager")
private TokenManager tokenManager;
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void controllerAspect() {
}
/**
* 接收到客户端请求时执行
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("controllerAspect()")
public Object execute(ProceedingJoinPoint pjp) throws Throwable {
// 从切点上获取目标方法
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
Method method = methodSignature.getMethod();
/**
* 验证Token
*/
if (method.isAnnotationPresent(TokenSecurity.class)) {
// 从 request header 中获取当前 token
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String token = request.getHeader(Constant.DEFAULT_TOKEN_NAME);
if (StringUtils.isEmpty(token)) {
throw new TokenException("客户端X-Token参数不能为空,且从Header中传入,如果没有登录,请先登录获取Token");
}
// 检查 token 有效性
if (!tokenManager.checkToken(token)) {
String message = String.format("Token [%s] 非法", token);
throw new TokenException(message);
}
}
// 调用目标方法
return pjp.proceed();
}
}
OAuth2.0: 这种方式安全等级最高,- 但是也是最复杂的。如果不是大型API平台或者需要给第三方APP使用的,没必要整这么复杂。
c.流量控制可借助Guava中对应RateLimiter模块功能,也可借助Redis高效响应机制自己设计,以调用方id+接口名称为KEY,设置接口调用上限即可,按天实时更新数据增量。
限流控制:主要用于服务的请求频率限制,避免由于服务吞吐量跟不上造成上层调用请求堆积过大而导致服务垮掉甚至应用奔溃问题。目前提供了单机版 限流和分布式限流功能。简而言之,通过限流控制,我们可以在方法级别的粒度控制到在XXX秒内最多接收XXX次调用。
并发控制:与限流控制类似,并发控制更加强调的是并发量。该功能能够保证服务在任何时刻的并发量控制。目前提供了单机和分布式两个版本的并发控 制。简而言之,通过并发控制,我们可以在方法级别的粒度控制到某个服务同时间最多不能超过XXX次请求被调用。