You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Onfido沙箱创建Check时Swift请求报422错误求助

解决Onfido沙箱创建Check时Swift代码返回422验证错误的问题

我帮你分析下这个问题——这种Python/curl能正常调用,但iOS Swift代码返回422 Unprocessable Entity的情况,基本都是请求格式、参数编码或者HTTP头的细节差异触发了Onfido的API验证规则。咱们结合代码对比来排查和解决:

核心差异点排查

首先对比你的Python和Swift代码,重点看这几个地方:

1. 确认Content-Type请求头是否正确

Onfido的API要求请求体必须是application/json格式,Python的requests.post(url, json=payload)会自动帮你设置这个头,但Swift的URLSession不会默认设置,如果你漏加或者设置错了格式(比如写成application/x-www-form-urlencoded),服务器会把你的JSON请求体当成表单数据解析,直接触发参数验证失败。

正确的Swift设置方式:

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

2. 检查JSON序列化的正确性

Swift中用JSONSerialization序列化字典时,要确保你的payload是合法的JSON类型:

  • 数组必须是[Any]类型(比如report_names必须是["identity"]而不是字符串"identity")
  • 不要包含JSON不支持的类型(比如自定义对象、nil,要用NSNull代替nil)

另外,建议捕获序列化错误,避免请求体为空或格式错误:

do {
    request.httpBody = try JSONSerialization.data(withJSONObject: payload, options: [])
} catch {
    print("JSON序列化失败:\(error.localizedDescription)")
    return
}

3. 对比实际发送的请求体

用抓包工具(比如Charles、Proxyman)分别捕获Python和Swift的请求,对比两者的请求体内容:

  • 检查参数名是否拼写正确(比如applicant_id不要写成applicantId)
  • 检查数组格式是否正确(比如report_names是不是数组,而不是单个字符串)
  • 检查是否有遗漏必填参数(Onfido创建Check必须有applicant_id和至少一个report_names)

4. 验证Authorization头格式

确保Swift代码中的授权头格式和Python一致:Token token=你的沙箱API密钥,注意空格和大小写,不要写成Bearer或者其他格式。

修正后的完整Swift代码示例

import Foundation

func createOnfidoCheck() {
    guard let apiUrl = URL(string: "https://api.sandbox.onfido.com/v3.3/checks") else {
        print("无效的API地址")
        return
    }
    
    var request = URLRequest(url: apiUrl)
    request.httpMethod = "POST"
    
    // 设置正确的HTTP头
    request.setValue("Token token=你的沙箱API密钥", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    // 构造符合要求的请求参数
    let requestPayload: [String: Any] = [
        "applicant_id": "你的申请人ID",
        "report_names": ["identity"] // 必须是数组类型,不能是单个字符串
    ]
    
    // 序列化JSON并设置请求体
    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: requestPayload, options: [])
    } catch {
        print("JSON序列化出错:\(error.localizedDescription)")
        return
    }
    
    // 发送请求并处理响应
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("请求出错:\(error.localizedDescription)")
            return
        }
        
        guard let httpResponse = response as? HTTPURLResponse else {
            print("未收到HTTP响应")
            return
        }
        
        print("响应状态码:\(httpResponse.statusCode)")
        
        if let responseData = data {
            do {
                let responseJson = try JSONSerialization.jsonObject(with: responseData, options: .allowFragments)
                print("响应内容:\(responseJson)")
            } catch {
                print("解析响应JSON失败:\(error.localizedDescription)")
                print("原始响应内容:\(String(data: responseData, encoding: .utf8) ?? "无原始数据")")
            }
        }
    }
    task.resume()
}

// 调用创建Check的函数
createOnfidoCheck()

额外调试技巧

如果还是报错,直接打印Onfido返回的错误详情(就是代码里的原始响应内容),里面会明确告诉你哪个参数不符合要求,比如"errors": [{"field": "report_names", "message": "must be an array"}],根据提示直接修正即可。

内容的提问来源于stack exchange,提问作者L.L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:44:12