curl POST 有效但 ionic this.http.post 无效
curl POST works but ionic this.http.post doesn't
我正在努力让离子 this.http.post
工作。
如果我在我的终端中使用这个 curl 效果很好:
curl -v -X POST \
https://myuser-name:ijF3Ui7VYVbbSejmwsnVVo@appdb.mysite.com:5984/_session \
-d 'name=app&password=ijF3Ui7VYVbbSejmwsnVVo'
它给我以下输出:
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 37.1.96.50...
* TCP_NODELAY set
* Connected to app.mysite.com (37.1.96.49) port 5984 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: app.mysite.com
* Server certificate: COMODO RSA Domain Validation Secure Server CA
* Server certificate: COMODO RSA Certification Authority
* Server auth using Basic with user 'myuser-name'
> POST /_session HTTP/1.1
> Host: app.mysite.com:5984
> Authorization: Basic cDpkTUQySzg0a2lqRjNVaTdWWVZiYlNlam13c25WVm8=
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 52
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 200 OK
< Set-Cookie: AuthSession=ZWhzLWFwcDo1OUFENThGRjruBtcPzHcqc1sC9WXrcWI7R27_Mg; Version=1; Secure; Path=/; HttpOnly
< Server: CouchDB/1.6.1 (Erlang OTP/18)
< Date: Mon, 04 Sep 2017 13:45:35 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 43
< Cache-Control: must-revalidate
<
{"ok":true,"name":null,"roles":["_admin"]}
* Connection #0 to host app.mysite.com left intact
我的离子 POST 代码如下所示:
login(callerName:string):any
// Make sure we have a CouchDB session so that PouchDB can access the CouchDB database
{
console.log('Authentication: login(): Login function called from ' + callerName);
return new Promise(resolve => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let credentials = {
name: COUCHDB_USER,
password: COUCHDB_PASSWORD
};
let result = {
success: false,
data: []
};
console.log('Authentication: login(): credentials = ' + JSON.stringify(credentials));
// NOTE:
//
// If POST is called with COUCHDB_SERVER with no auth in the url I get the error: Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session"
//
// If POST is called with COUCHDB_SERVER WITH auth in url I get the error: Response with status: 0 for URL: null
// This 'might' mean:
// Timeout from server
// Request not sent
// Requesting an unreachable url
// ...
// This WORKS with curl in terminal
//
// With auth in url: https://myuser-name:ijF3Ui7VYVbbSejmwsnVVo@app.mysite:5984/_session
// Without auth in url: https://app.mysite.com:5984/_session
//
this.http.post(COUCHDB_SERVER + '/_session', JSON.stringify(credentials), {headers: headers})
.subscribe(res => {
var details = res.json();
console.log('Authentication: login(): SuperLogin successful login: res = ' + JSON.stringify(details));
result.success = true;
result.data = details;
resolve(result);
},
(err) => {
console.log('Authentication: login(): Login failed err = ' + err);
let details = err.json();
result.success = false;
result.data = details;
resolve(result);
});
});
}
如果我在 ionic 中尝试 POST 而 url 中没有授权,我会收到一条合理的错误消息:
Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session"
但是,如果我将身份验证添加到 url,我会收到一条错误消息,但没有告诉我问题所在:
Response with status: 0 for URL: null
我不明白为什么它适用于 curl 但不适用于 ionic http.post.
无论是 运行 ionic serve
还是 运行 iPhone 上的应用程序,我都遇到了同样的问题。
更新
我在 Chrome 中有 运行 离子应用程序,现在有一个更好的错误:
error: "unauthorized", reason: "Authentication required."
很明显我没有得到正确的 POST 请求,但不明白为什么。
ionic认证失败,因为this.http.post
的用法不正确:第二个参数应该是HTTP请求body object(JSON,credential
object),不是字符串。例子请参考https://angular.io/guide/http
发送 HTTP 请求的代码为:
this.http.post(COUCHDB_SERVER + '/_session', credentials, {headers: headers})...
在curl中有效,在ionic中无效 -- 那是因为curl发送的HTTP请求的Content-Type
是application/x-www-form-urlencoded
,而curl的语法正确。
我要在 URL 中添加 auth 吗? -- 我猜这意味着 URL 中的 myuser-name:ijF3Ui7VYVbbSejmwsnVVo@
部分。答案是否定的:它在 curl 中有效(在请求中添加 Authorization
header)但在浏览器中无效,请查看 Pass username and password in URL for HTTP Basic Auth 了解详情。
更新:似乎在 CouchDB 中强制执行基本身份验证。为了满足,可以在HTTP请求中手动添加Authorization
header:
headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password))
我正在努力让离子 this.http.post
工作。
如果我在我的终端中使用这个 curl 效果很好:
curl -v -X POST \
https://myuser-name:ijF3Ui7VYVbbSejmwsnVVo@appdb.mysite.com:5984/_session \
-d 'name=app&password=ijF3Ui7VYVbbSejmwsnVVo'
它给我以下输出:
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 37.1.96.50...
* TCP_NODELAY set
* Connected to app.mysite.com (37.1.96.49) port 5984 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: app.mysite.com
* Server certificate: COMODO RSA Domain Validation Secure Server CA
* Server certificate: COMODO RSA Certification Authority
* Server auth using Basic with user 'myuser-name'
> POST /_session HTTP/1.1
> Host: app.mysite.com:5984
> Authorization: Basic cDpkTUQySzg0a2lqRjNVaTdWWVZiYlNlam13c25WVm8=
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 52
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 200 OK
< Set-Cookie: AuthSession=ZWhzLWFwcDo1OUFENThGRjruBtcPzHcqc1sC9WXrcWI7R27_Mg; Version=1; Secure; Path=/; HttpOnly
< Server: CouchDB/1.6.1 (Erlang OTP/18)
< Date: Mon, 04 Sep 2017 13:45:35 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 43
< Cache-Control: must-revalidate
<
{"ok":true,"name":null,"roles":["_admin"]}
* Connection #0 to host app.mysite.com left intact
我的离子 POST 代码如下所示:
login(callerName:string):any
// Make sure we have a CouchDB session so that PouchDB can access the CouchDB database
{
console.log('Authentication: login(): Login function called from ' + callerName);
return new Promise(resolve => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let credentials = {
name: COUCHDB_USER,
password: COUCHDB_PASSWORD
};
let result = {
success: false,
data: []
};
console.log('Authentication: login(): credentials = ' + JSON.stringify(credentials));
// NOTE:
//
// If POST is called with COUCHDB_SERVER with no auth in the url I get the error: Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session"
//
// If POST is called with COUCHDB_SERVER WITH auth in url I get the error: Response with status: 0 for URL: null
// This 'might' mean:
// Timeout from server
// Request not sent
// Requesting an unreachable url
// ...
// This WORKS with curl in terminal
//
// With auth in url: https://myuser-name:ijF3Ui7VYVbbSejmwsnVVo@app.mysite:5984/_session
// Without auth in url: https://app.mysite.com:5984/_session
//
this.http.post(COUCHDB_SERVER + '/_session', JSON.stringify(credentials), {headers: headers})
.subscribe(res => {
var details = res.json();
console.log('Authentication: login(): SuperLogin successful login: res = ' + JSON.stringify(details));
result.success = true;
result.data = details;
resolve(result);
},
(err) => {
console.log('Authentication: login(): Login failed err = ' + err);
let details = err.json();
result.success = false;
result.data = details;
resolve(result);
});
});
}
如果我在 ionic 中尝试 POST 而 url 中没有授权,我会收到一条合理的错误消息:
Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session"
但是,如果我将身份验证添加到 url,我会收到一条错误消息,但没有告诉我问题所在:
Response with status: 0 for URL: null
我不明白为什么它适用于 curl 但不适用于 ionic http.post.
无论是 运行 ionic serve
还是 运行 iPhone 上的应用程序,我都遇到了同样的问题。
更新
我在 Chrome 中有 运行 离子应用程序,现在有一个更好的错误:
error: "unauthorized", reason: "Authentication required."
很明显我没有得到正确的 POST 请求,但不明白为什么。
ionic认证失败,因为this.http.post
的用法不正确:第二个参数应该是HTTP请求body object(JSON,credential
object),不是字符串。例子请参考https://angular.io/guide/http
发送 HTTP 请求的代码为:
this.http.post(COUCHDB_SERVER + '/_session', credentials, {headers: headers})...
在curl中有效,在ionic中无效 -- 那是因为curl发送的HTTP请求的Content-Type
是application/x-www-form-urlencoded
,而curl的语法正确。
我要在 URL 中添加 auth 吗? -- 我猜这意味着 URL 中的 myuser-name:ijF3Ui7VYVbbSejmwsnVVo@
部分。答案是否定的:它在 curl 中有效(在请求中添加 Authorization
header)但在浏览器中无效,请查看 Pass username and password in URL for HTTP Basic Auth 了解详情。
更新:似乎在 CouchDB 中强制执行基本身份验证。为了满足,可以在HTTP请求中手动添加Authorization
header:
headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password))