一、前言
在前后端完全分离的开发模式或者说是架构模式下,后端开发者只需要编写后端接口,特别是restful风格接口更为常见。那么暴露给外面的接口大概有三个常见。1、给后台系统调用的接口,2、对客端应用的接口(APP或者H5页面),3、第三方系统调用接口。那么同一个系统下怎么保证接口的安全性。应该怎么设计,本节做一下子总结
二、token的制作
系统对外提供部分接口,为了保证软件数据的安全性,可以通过设置token令牌来校验请求方是否合法。 比较流行的JWT来实现。
实现步骤:客户端每次访问接口的时候,要在header中携带token令牌,然后在项目的拦截器中使用相应的策略配置拦截这些对外接口的请求(例如这一类接口的url统一配置为/api/开头),拦截到请求后从header中得到token进行校验,校验通过后即可放行。通过不了返回相应状态码,客户端得到状态码携带账号和密码向服务端申请token,服务端验证账号密码合法后生成token返回,token具有时效性。
三、实现token
引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
生成token与校验token
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
public class TokenManager {
//私钥
private static final String SECRET = "Axmk89Li3Aji9M";
//过期时间1分钟
private static final int expiresTime = 60000;
public static String createToken(Long userId){
//获取加上过期时间后的时间
Date nowDate = new Date();
System.out.println(nowDate);
Date expiresDate = new Date(System.currentTimeMillis()+expiresTime);
Map<String,Object> map = new HashMap<String,Object>();
map.put("alg", "HS256");
map.put("typ", "JWT");
String token = JWT.create().withHeader(map) //请求头
.withClaim("iss", "Service") //签发方
.withClaim("aud", "Client") //接收方
.withClaim("userId", null==userId?null:userId.longValue()) //存储信息,用户ID
.withIssuedAt(nowDate) //当前时间
.withExpiresAt(expiresDate) //过期时间
.sign(Algorithm.HMAC256(SECRET)); //私钥
return token;
}
public static boolean verifyToken(String token){
try{
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
verifier.verify(token);
//DecodedJWT verify = verifier.verify(token);
//return verify.getClaims(); //能返回数据集合(用于在jwt中存储一些数据)的,但是由于这一版本只需要核验token是否合法,所以只需要返回true和false;
return true;
}catch(Exception e){
log.error(e.getMessage(), e);
return false;
}
}
}
四、校验接口
当然获取token的接口不需要token,可以直接请求,只是系统双方会约定获取token的参数,涉及到账号,秘钥之类的,还有传输参数涉及的加密方式。
我们可以通过编写过滤器来校验传过来的接口和携带的token
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String path = request.getURI().getPath();
if (pathMatcher(resourceUrl, path)) {
return chain.filter(exchange);
}
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
//获取token
String token= request.getHeaders().getFirst("token");