最近做了一个奇门接口对接问题。遇到了验签问题,特和大家分享下。
目前的需求是在奇门发布一个接口。本地接口是post请求,参数在body中存储。
奇门的接口配置流程可以参考官方文档如下链接内容:
奇门官方集成接入说明
下面说一说我的接口配置大概情况:
例如我本地有一个post请求,带参数的

当前请求在服务接口没有加入淘宝奇门验签的时候,是正常请求和返回的。
当加入淘宝估计方法验签后,应该是返回验签失败。入下图显示:

以上的返回格式是奇门接口要求的验签返回错误格式,参考如下的工具类代码格式
/**
* 使用该方法同时请务必要阅读该方法的源码,大致了解该方法的实现。
*
* 如果验签失败则需要返回验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功;
*
* 如果正确的请求老是误认为验签错误了,则确认以下几点:1编码是否UTF82 2密钥是否写错了 3request如果是json,xml类型则(form则忽略)确认inputstream是否被读取过了?如果需要使用body但不想改动麻烦,可以先执行验签,
* 然后在验签结果中获取body(checkResult.getRequestBody()方法)来执行业务逻辑
*
*/
CheckResult result = SpiUtils.checkSign(request, targetAppSecret);? //这里执行验签逻辑
if(!result.isSuccess()) { //如果验签失败则需要返回 验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功
HttpSampleResponse httpSampleResponse = new HttpSampleResponse();
httpSampleResponse.setErrorMessage("Illegal request");
httpSampleResponse.setErrorCode("sign-check-failure");
httpSampleResponse.setFlag("failure);
//return
}
想本地验证验签的成功与否,可以去奇门日志中查找对应的请求记录,找到对应内容放入本地posman中测试本地方法。

通过以上测试发现问题:使用奇门测试工具的转发url(已加签)和报文,在本地无法验证通过。
通过反复尝试,发现只要是本地body带内容的无法通过验签:
主要我现在用测试的posman的body参数值有,但是使用淘宝的验签代码里面的这段看了下获取不到body的内容
String body = WebUtils.getStreamAsString(request.getInputStream(), charset);这个body内容是空的。
我本地的接口代码如下:
@POST
@Path("authenticationQMPost")
@Produces(MediaType.APPLICATION_JSON)
public String authenticationQMPost(
String params,
@Context HttpServletRequest request,
@Context HttpServletResponse response) {
//设置响应头编码格式
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=UTF-8");
Map<String, Object> resultMap = FastMap.newInstance();
PrintWriter out = null;
String resultStr = "";
try {
out = response.getWriter();
request.setCharacterEncoding("utf-8");
CheckResult result = QiMenUtils.checkSign(request, targetAppSecret, params);//这里执行验签逻辑
if (!result.isSuccess()) { //如果验签失败则需要返回 验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功
resultStr = authenticationFailure(result.getRequestBody());
} else {
if (null == params || "" == params) {
resultStr = authenticationSuccess("test post succ,body无内容");
} else {
resultStr = authenticationSuccess("test post succ,body内容:" + params);
}
}
} catch (Exception e) {
if (Debug.errorOn()) {
Debug.logError(e, module);
}
log.error("", e);
resultStr = authenticationFailure(e.getMessage());
}
out.println(resultStr);
out.flush();
out.close();
return null;
}
由于我本地的方法的params是可以获取到body的内容,所以确定修改淘宝奇门的验签方法中的获取body的方法。
public static CheckResult checkSign(HttpServletRequest request, String secret, String bodyStr) throws IOException {
CheckResult result = new CheckResult();
String ctype = request.getContentType();
String charset = WebUtils.getResponseCharset(ctype);
if (null != ctype && !"".equals(ctype)) {
if (!ctype.startsWith("application/json") && !ctype.startsWith("text/xml") && !ctype.startsWith("application/xml") && !ctype.startsWith("text/plain")) {
if (!ctype.startsWith("application/x-www-form-urlencoded")) {
throw new RuntimeException("Unspported SPI request");
}
boolean valid = checkSignInternal(request, (Map) null, (String) null, secret, charset);
result.setSuccess(valid);
} else {
//String body = WebUtils.getStreamAsString(request.getInputStream(), charset);
boolean valid = checkSignInternal(request, (Map) null, bodyStr, secret, charset);
result.setSuccess(valid);
result.setRequestBody(bodyStr);
}
} else {
//String body = WebUtils.getStreamAsString(request.getInputStream(), charset);
boolean valid = checkSignInternal(request, (Map) null, bodyStr, secret, charset);
result.setSuccess(valid);
result.setRequestBody(bodyStr);
}
return result;
}
通过以上调整,从奇门接口日志中拿到的“转发url参数”和“奇门转发报文” 可以正常通过本地的方法验签。
使用验签注意:
* 使用Sdk的SpiUtils.checkSign来执行验签,同时请务必要阅读该方法的源码,大致了解该方法的实现。
*
* 如果验签失败则需要返回验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功;
*
* 如果正确的请求误认为验签错误了,则确认以下几点:
* 1编码是否UTF8
* 2密钥是否写错了,特别是沙箱和线上密钥别搞错
* 3request如果是json,xml类型(form不用理会)则确认inputstream是否被读取过了?如果需要使用body但不想改动麻烦,可以先执行验签,
* 然后在验签结果中获取body(checkResult.getRequestBody()方法)来执行业务逻辑
* 4上层框架是否有做封装导致参数变更
* 如果名以上几点检查没问题,请提供sdk md5前(SpiUtils 类里的方法 String sign(Map<String, String> params, String body, String secret, String charset)
)的最终字符串给小二协助排查
淘宝奇门接口验签实战与解决办法

本文档分享了在对接淘宝奇门接口时遇到的验签问题及解决方案。在接口配置过程中,发现本地POST请求加入验签后返回验签失败。问题在于奇门接口验签代码无法正确获取请求的body内容。通过调整验签方法中获取body的方式,成功实现了本地验签。验签注意事项包括:使用正确的编码UTF8,核对密钥,确保输入流未被提前读取,以及避免上层框架对参数的改变。若遇到问题,可提供验签前的字符串给官方协助排查。
1532

被折叠的 条评论
为什么被折叠?



