1.前言
在日常的开发需求中,除了从负载业务网关到后端提供服务应用的正向请求外,也会有其他第三方服务调用后端服务指定接口,这些接口通常是些查询或者是状态调整等非核心类型。那设计中就需要考虑如何绕过后端的鉴权模块,而且需要提供约定校验进行接口请求。
2.设计思路
客户端设计
客户端需要采用http的框架封装请求,完成调用工作。本案例是实现查询网络流媒体平台以及开启设备流媒体通道功能,采用的是开源的Forest框架进行声明式调用。
@Address(source = WvpAddressSource.class)
@BaseRequest(interceptor={RemoteWvpInterceptor.class},timeout = 30000,readTimeout = 30000)
@Retry(maxRetryCount = "3", maxRetryInterval = "30",condition = RemoteWvpSuccessCondition.class)
public interface RemoteWvpService {
/**
* 查询WVP平台上的通道或流信息
* @param deviceOrAppId
* @param channelOrStreamId
* @return
*/
@Get("/api/v1/streamorchannel/{0}/{1}")
ForestResponse<WVPResult<Map<String,Boolean>>> findWebVideoResource(String deviceOrAppId, String channelOrStreamId);
/**
* 调用在线设备的WVP平台播放功能,获取RTSP与RTMP地址
* @param deviceId
* @param channelId
* @return
*/
@Get("/play/start/{deviceId}/{channelId}")
ForestResponse<DeferredResult<WVPResult>> remotePlayChannel(@Var("deviceId") String deviceId, @Var("channelId") String channelId);
Forest请求wvp平台的接口代码
客户端加密的方式采用Forest的拦截器功能,用设置@BaseRequest属性中interceptor值的方式进行指定。加密的方式采用获取请求实体中参数值与日期拼接的字符串,进行不可逆的加密处理。
将加密后的密文,放置在请求头中,并在服务端中进行校验。
@Component
@Import(BCryptPasswordEncoder.class)
public class RemoteWvpInterceptor<ForestResponse> implements Interceptor<ForestResponse> {
private final static Logger log = LoggerFactory.getLogger(RemoteWvpInterceptor.class);
@Autowired
private BCryptPasswordEncoder encoder;
@Override
public boolean beforeExecute(ForestRequest request) {
//拼接请求路径
String requestPath = request.getURI().getPath();
//去除userInfo的信息
request.setUserInfo("");
//获取当天的日期
String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//对请求参数与时间进行加密
String encodedStr = encoder.encode(formattedDate + File.separator + requestPath + formattedDate);
//设置客户端容许访问的头信息
request.addHeader(ThirdAssociateEnum.ALLOW_OUT_CLIENT_API.getValue(),encodedStr);
log.info("调用WVP平台接口{}的头信息为{}",requestPath,encodedStr);
return true;
}
}
Forest请求时的加密拦截器
需要注意的是,Forest请求默认会有请求超时时间,如果业务容许的时间窗口短,可以采用异步的方式进行调用。如果对时间敏感的话,需要业务端设置重试机制,服务端进行相应的处理。
服务端设计思考
服务端的接口鉴权请求分为四种:
1.外部GateWay转发的用户请求,需要进行正常的鉴权。
2.外部GateWay的服务间调用求求,不需要进行鉴权。
3.内部微服务间的调用,请求中携带token令牌。
4.外部第三方服务调用,越过鉴权且需要进行请求校验。
还有一个问题:
如何才能动态的指定某一个接口进行校验,而不是进行编程式耦合
请思考一下。