Unity WebRequest请求Moodle API出现SSL CA证书错误求解
问题描述
需要通过GET请求获取Moodle API令牌,接口格式如下:https://your_moodle_domain/login/token.php?username=YOUR_USERNAME&password=YOUR_PASS&service=moodle_mobile_app
- 浏览器、Python、JS等渠道发起该请求均可正常返回令牌
- 仅Unity中使用C#的
UnityWebRequest发起请求时报错,报错参考截图:
当前实现代码
using System.Collections; using System.Collections.Generic; using System.Net; using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; public class testReqests : MonoBehaviour { public string url = "https://your_moodle_domen/login/token.php?username=YOUR_USERNAMEr&password=YOUR_PASS&service=moodle_mobile_app"; void Start() { StartCoroutine(LoadFromServer(url)); } IEnumerator LoadFromServer(string url) { // var cert = new ForceAcceptAll(); UnityWebRequest request = UnityWebRequest.Get(url); // request.certificateHandler = cert; yield return request.SendWebRequest(); if(request.isNetworkError){ Debug.Log(request.error); } else Debug.Log(request.downloadHandler.text); // cert?.Dispose(); } } public class ForceAcceptAll : CertificateHandler { protected override bool ValidateCertificate(byte[] certificateData) { return true; } }
已尝试操作
- 编写了自定义
CertificateHandler实现全SSL证书放行的临时方案,未解决问题 - 已确认目标Moodle服务器的SSL证书配置无异常
可行排查与解决步骤
按优先级依次排查:
修正URL拼写错误
现有代码里的域名拼写错误:your_moodle_domen正确应为your_moodle_domain;同时username参数值末尾多写了一个多余的r,先修正这两个拼写问题,排除路径错误导致的连接失败。强制指定TLS协议版本
Unity默认的安全协议配置可能和Moodle服务器要求不匹配,目前绝大多数站点已经禁用TLS1.0/1.1,在发起请求前添加如下代码,强制启用TLS1.2/1.3:// 写在UnityWebRequest.Get()之前 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;修正错误状态判断逻辑
Unity 2020及后续版本已经废弃isNetworkError属性,原判断逻辑会漏掉HTTP错误(比如403、404、500),把错误判断代码替换为:if (request.result != UnityWebRequest.Result.Success) { Debug.Log($"请求错误:{request.error}, 状态码:{request.responseCode}"); } else { Debug.Log(request.downloadHandler.text); }打印状态码可以快速定位是连接层错误还是服务端返回了业务错误。
补全必要请求头
部分Moodle站点会校验请求的User-Agent字段,UnityWebRequest默认的UA可能被WAF或站点规则拦截,手动添加常规浏览器UA:request.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");正确启用证书放行逻辑(如果需要)
如果确实需要临时跳过证书校验,要把代码里注释的request.certificateHandler = cert;放开,确保在SendWebRequest()调用前完成赋值,请求结束后及时Dispose证书处理器。检查Unity权限配置
打开Player Settings -> Other Settings -> Configuration,确认Internet Access设置为Require;如果是移动端打包,还要检查对应平台的网络权限是否正常声明,避免被系统拦截网络请求。抓包对比请求差异
如果以上步骤都没解决,用本地抓包工具抓取Unity发出的请求,和浏览器正常成功的请求做对比,检查是否存在头字段缺失、请求被本地防火墙/代理拦截的问题。
内容的提问来源于stack exchange,提问作者EPSILOM

