ios - 从 ionic 本机 http 客户端发布数据时更改对象属性的顺序
问题描述
我正在开发将在 android 和 iOS 平台上使用的 ionic 应用程序。应用程序使用一个端点将用户数据发布到后端。后台发布的数据如下:
{
"name": "Citizen Foo",
"emailAddress": "citizen.foo@gmail.com",
"role": "citizen"
}
出于安全目的,正在发送的每个请求都经过验证。为了做到这一点,客户端会随每个请求发送授权标头。后端为每个请求创建一个,并将其与客户端发送的一个匹配,然后仅响应,否则抛出异常。为了创建授权标头,通过 post 请求发送的数据也是逻辑的一部分。我已经简化了这个逻辑,因为实际问题不同,但这部分对于理解问题很重要。
以下是客户端的示例代码:
var sRequestBody = JSON.stringify(data);
var requestBodyBytes = this.getByteArray(unescape(encodeURIComponent(sRequestBody)));
var authHeader = md5.base64(requestBodyBytes);
var headers = {};
headers['Authorization'] = authHeader;
this.nativeHttp.setDataSerializer('json');
this.nativeHttp.clearCookies();
this.nativeHttp.setSSLCertMode('nocheck');
return Observable.fromPromise(this.nativeHttp.post(url, data, headers));
然后,后端是 asp.net web api,以相同的方式计算授权,并将其与客户端发送的一个匹配,如果匹配则给出响应。
var rawContent = await content.ReadAsByteArrayAsync();
var stringContent = content.ReadAsStringAsync().Result;
var hash = md5.ComputeHash(rawContent);
var authorization = Convert.ToBase64String(hash);
if (authHeader != authorization)
throw;
当上述调用是从 android 发出时,
value of dataString on client is
"{"name":"Citizen Foo","emailAddress":"citizen.foo@gmail.com","role":"citizen"}"
value of stringContent on server is
"{""name"":""Citizen Foo"",""emailAddress"":""citizen.foo@gmail.com"",""role"":""citizen""}"
它允许来自 android 应用程序的请求。
当在 iOS 上运行相同并进行用户后调用时,
Value of dataString on client is
"{"name":"Citizen Foo","emailAddress":"citizen.foo@gmail.com","role":"citizen"}"
Value of stringContent on server is
"{""name"":""Citizen Foo"",""role"":""citizen"",""emailAddress"":""citizen.foo@gmail.com""}"
并且它不允许来自 iOS 应用程序的请求。
它发生的唯一原因是当从 iOS 发出请求时,用户对象在后端被序列化/接收的方式。发送时的属性顺序是name,emailAddress,role
。虽然它是与 order 一起收到的name,role,emailAddress
。因此,服务器端计算的授权值与来自客户端的 authHeader 不同,调用被终止。
stringContent
在服务器端添加只是为了调试和了解服务器接收到的内容。客户端上对象属性的顺序与服务器端接收到的对象属性不同。当从 iOS 平台发出请求时,有没有办法维护对象属性的顺序?以任何方式解决此问题的方向表示赞赏。
解决方案
对我们有用的一种解决方案是:
this.httpClient.setDataSerializer('utf8');
response = await this.httpClient.post(url, JSON.stringify(postBody), {'Content-Type': 'application/json'});
所以这里的关键点是:
- utf8 作为数据序列化器
- 身体必须被字符串化
- header 'Content-Type': 'application/json' 必须设置
推荐阅读
- wordpress - 如何从主题函数文件中删除gutenberg_render_title_tag?
- python - python加载A.so文件,其某些函数在B.so文件中定义
- html - 如何在悬停时显示跨度,然后在未悬停时不隐藏?
- github - Github 博客图片上传失败(Markdown 路径)
- c# - 为什么'if'会停止音乐并且不允许我在其中播放任何新音乐?以及如何使它工作?
- r - dplyr::mutate() -- 在 tibble 嵌套列表中,如何忽略 NULL 嵌套列表?
- python - Streamlit、Flask、Fastapi:如何将压缩文件上传到我的网络应用程序并使其可下载?
- algorithm - 如何在另一个数据仓库平台中解密 DB2 数据
- flutter - Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?
- typescript - 启用 TypeScript 以查找 VSCode 中没有默认导出的文件