一、前言
在前后端完全分离的开发模式或者说是架构模式下,后端开发者只需要编写后端接口,特别是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");
一、引言
随着互联网技术的发展,Web系统接口设计在各类应用中扮演着越来越重要的角色。一个良好的接口设计可以提高系统的可维护性、可扩展性和用户体验。本文将对Web系统接口设计进行全面总结。
二、接口设计原则
- 明确性:接口定义应清晰明确,避免歧义,确保调用者正确理解接口功能。
- 简洁性:设计时应尽量减少不必要的复杂性,使接口易于使用和理解。
- 安全性:确保接口数据传输和存储的安全性,防止数据泄露和未经授权的访问。
- 可扩展性:为未来功能扩展预留空间,避免后期大量修改。
- 稳定性:确保接口在各种情况下都能稳定运行,减少因错误或异常导致的服务中断。
三、接口设计要素
- 请求方法(HTTP Verbs):合理使用GET、POST、PUT、DELETE等请求方法,明确各方法的用途。
- 路由(Routing):合理规划接口的URL结构,使其具有清晰的组织结构和语义。
- 参数传递:根据需求选择合适的参数传递方式(如query string, path variables, request body等)。
- 错误处理:定义统一的错误码和错误信息格式,以便于排查问题。
- 日志与监控:实施接口访问日志记录和性能监控,以便及时发现和解决问题。
四、最佳实践
- 版本控制:为接口使用版本号,以便于升级和维护老版本。
- 缓存策略:合理利用缓存减少不必要的请求,提高系统性能。
- 限流与防刷:设置接口访问限制,防止恶意请求对系统的冲击。
- 文档化:提供详细、准确的接口文档,便于开发者理解和使用。
- 测试与验证:实施接口测试和压力测试,确保其稳定性和性能。
五、总结与展望
一个良好的Web系统接口设计对于提高系统的整体性能和用户体验至关重要。在未来的发展中,随着技术的进步和应用需求的不断变化,Web系统接口设计将面临更多的挑战和机遇。我们应该不断学习新的设计理念和技术,不断优化和改进接口设计,以满足不断变化的市场需求。