后端接口为了安全考虑, 通常会增加接口参数签名认证;增加接口参数签名认证, postman直接调用,会认证失败, 需要实现一套和前端项目一样的签名动作;
api参数签名认证api参数签名认证原理 api-time: 本次API调用的有效时间,超过该时间调用失效,避免重放攻击 api-key: 与api-secret是一个pair对,一一对应,知道了api-key即可查询到api-secret api-signature: api-secret和message一起生成的签名,这里的message一般包括api-key, 请求方法, get, post参数 api-signature的生成规则一般为: crypto-js的hmac_sha256,输出值需转化为base64字符串
postman pre-request签名计算 var apiKey = pm.globals.get("apiKey"); var apiSecret = pm.globals.get("apiSecret"); const query = pm.request.url.query; var keys = []; var map = {}; query?.each(e => { let disabled = e["disabled"]; if (!disabled) { let k = e["key"]; keys.push(k); map[k] = e["value"]; } }); const queryArr = []; keys.sort(); keys.forEach(k => { queryArr.push(k + "=" + map[k]); }); const queryStr = queryArr.join("&"); const body = JSON.stringify(JSON.parse(pm.request.body.raw.toString())); var method = request.method; var signArr = [apiKey, method.toLowerCase(), queryStr, body]; const signSrcStr = signArr.join('&'); console.log(signSrcStr); var signatureBase64 = CryptoJS.HmacSHA256(signSrcStr, apiSecret).toString(CryptoJS.enc.Base64); console.log("signatureBase64", signatureBase64); pm.environment.set("api-signature", signatureBase64); const timeStr = Math.round(new Date().getTime()); pm.environment.set("api-time", timeStr); pm.request.body = body; java后端签名计算 class ApiPreHandler { public static String generateHmac256(String msg, String key) { if (Objects.isNull(msg)) { return ""; } if (Objects.isNull(key)) { return msg; } final String algorithm = "HmacSHA256"; try { SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm); Mac mac = Mac.getInstance(algorithm); mac.init(secretKeySpec); byte[] bytes = mac.doFinal(msg.getBytes()); return Base64.getEncoder().encodeToString(bytes); } catch (Exception e) { LogUtils.error(e.getMessage(), e); return ""; } } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); String method = request.getMethod().toLowerCase(Locale.ROOT); String querySorted = getSortedQuery(request.getQueryString()); String body = request.getReader().lines().collect(Collectors.joining()); String apiSignature = request.getHeader("api-signature"); String signStrSrc = String.join("&", Lists.newArrayList(apiKey, method, querySorted, body)); log.info("requestURI: {}, singStrSrc={}", requestURI, signStrSrc); String calcSign = SecurityUtils.generateHmac256(signStrSrc, apiSecret); if (!Objects.equals(apiSignature, calcSign)) { log.error("api-signature denied, signStrSrc={}", signStrSrc); return false; } return true; } }