卷曲POST工作,但离子this.http.post没有

时间:2017-09-04 14:30:15

标签: http curl ionic2 xmlhttprequest couchdb

我正在努力让离子this.http.post起作用。

如果我在我的终端中使用这个卷曲它很有效:

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代码如下所示:

&#13;
&#13;
  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);
          });
    });
  }
&#13;
&#13;
&#13;

如果我在网上尝试POST而没有使用auth,我会得到一个明智的错误信息:

Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session"

但是如果我在网址中添加auth,我会收到一条错误消息,告诉我问题是什么:

Response with status: 0 for URL: null

我无法解决为什么它适用于curl但不适用于离子http.post。

无论是运行ionic serve还是在iPhone上运行应用程序,我都遇到同样的问题。

更新

我在Chrome中运行了离子应用程序,现在出现了更好的错误:

error: "unauthorized", reason: "Authentication required."

所以我很清楚我没有得到正确的POST请求,但却看不出原因。

1 个答案:

答案 0 :(得分:3)

身份验证在离子中失败,因为this.http.post的使用不正确:第二个参数应该是HTTP请求正文对象(JSON,credential对象),而不是字符串。例如,请参阅https://angular.io/guide/http

发送HTTP请求的代码是:

this.http.post(COUCHDB_SERVER + '/_session', credentials, {headers: headers})...

它适用于curl,但不适用于离子 - 这是因为curl发送的HTTP请求的Content-Typeapplication/x-www-form-urlencoded,而curl&# 39; s语法正确。

我应该在网址中添加auth吗? - 我想这意味着网址中的myuser-name:ijF3Ui7VYVbbSejmwsnVVo@部分。答案是否:它适用于curl(在请求中添加Authorization标题)但它无法在浏览器中工作,请查看Pass username and password in URL for HTTP Basic Auth以获取详细信息。

更新:似乎在CouchDB中强制进行基本身份验证。为了满足它,可以在HTTP请求中手动添加Authorization标头:

headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password))