4

I try to develop my new app with Ionic2. In this context, the user should be authenticated with a pre shared token which will be sent to the api (http request). As a response he get an access token with which he can use further api functions.

The problem is that when I send an HTTP request, I get as an error: {"_body":{"isTrusted":true},"status":200,"statusText":"Ok","headers":{},"type":3,"url":null}

In my desktop version everything works fine, but on Android I get this error. I still googled this error and I guess that the http request comes in conflict with other observables (Form observable).

I would be very pleased if someone could help me to avoid this "error". As a small hint: {"isTrusted":true} is the value of the event value of the method handleSubmit. Thank you :-)

Solution: This error was thrown because the api was not reachable (in my case due to a certificate error). When you have the same error: Check if type="3", then it is possible that your http target is also not reachable.

My template:

<ion-content padding class="token-auth">
  <form [ngFormModel]="authForm" (submit)="handleSubmit($event)">
    <ion-item>
      <ion-label floating>Device-ID</ion-label>
      <ion-input (keyup)="onKeyUp($event)" [ngFormControl]="token" type="text"></ion-input>
    </ion-item>

    <div *ngIf="error !== null"
         class="error-box">
      {{error.message}}
    </div>

    <button block type="submit" [disabled]="!authForm.valid">
      Register device
    </button>

  </form>
</ion-content>

Page source:

handleSubmit(event) : void {          
  this.tokenService.sendAccessTokenRequest(this.authForm.value.token, (err, code) => {
        this.error = {
            code : code,
            message : err
        };
    }, (accessToken, refreshToken, validTill) => {
        this.error = null;
    });
}

TokenService:

/**
 *
 * @param token
 * @param errCallback : (message : string, code : number) => any
 * @param callback : (accessToken : string, refreshToken : string, validTill : string) => any
 */
public sendAccessTokenRequest(token : string, errCallback, callback) {
    if (typeof token === 'undefined') {
        throw 'Token value must be set. ';
    }
    if (typeof errCallback === 'undefined') {
        errCallback = (code, message) => null;
    }
    if (typeof callback === 'undefined') {
        callback = (accessToken, refreshToken, validTill) => null;
    }

    console.log(`Should send token: ${token}`);

    this.sendPost(`/auth/login`, `application=XXX&device_token=${token}`)
        .subscribe(res => {
            console.log("Device verified: "+JSON.stringify(res));
            let {
                access_token,
                refresh_token,
                valid_till
            } = res.data.token;
            this._saveTokenData(access_token, refresh_token, new Date(valid_till));
            callback(access_token, refresh_token, valid_till);
        },
        err => {
            // error is here!
            if (err && err._body) {
                console.log("ERROR: "+JSON.stringify(err));
                try {
                    let bodyData = JSON.parse(err._body);
                    let responseData = bodyData["data"];
                    let token:MessageResponse = responseData.token;
                    if (token && typeof token.code !== 'undefined' && typeof token.userMessage !== 'undefined') {
                        errCallback(token.userMessage, token.code);
                    } else {
                        errCallback(bodyData);
                    }
                } catch (e) {
                    errCallback(e);
                }
            }
        },
        () => console.log("access token request successful")
    );
}

// just an excerpt from other url
sendPost(link : string, params : string, header : Object = {}) {
    console.log("SEND POST");
    link = this._enforceSlashAtStringStart(link);
    return this.http.post(`${this.base_url}${link}`, params, {
        headers : this._mergeHeader(this.getHeader(), header)
    }).map(res => { console.log("Start mapping! "); return res.json(); });
}

// EDIT: added function _saveTokenData
private _saveTokenData(accessToken : string, refreshToken : string, validTill : Date) {
        if (!accessToken || !refreshToken || !validTill) {
            throw new Error('access token data can not be null or undefined! ');
        }

        console.log("TOKEN SAVED!");

        this._accessToken = accessToken;
        this._refreshToken = refreshToken;
        this._validTill = validTill;

        // this._storage = new Storage(LocalStorage);
        this._storage.set(TOKEN_STORAGE_KEY, JSON.stringify({
            access_token : accessToken,
            refresh_token : refreshToken,
            valid_till : validTill.toString()
        }));
    }

And last but not least the logs:

14    256534   log      Should send token: XXXXXXXXXXXXXX
15    256548   log      SEND POST
16    256750   log      ERROR: {"_body":{"isTrusted":true},"status":200,"statusText":"Ok","headers":{},"type":3,"url":null}
CapCa
  • 556
  • 1
  • 6
  • 15
  • What does the `_saveTokenData` method do? – Thierry Templier Mar 08 '16 at 12:48
  • Oh sorry, I added this function. It saves the three variables only to local storage. – CapCa Mar 08 '16 at 12:55
  • Okay. Could you add to the trace the complete URL of the request. I mean "`${this.base_url}${link}`". Thanks! – Thierry Templier Mar 08 '16 at 12:59
  • The logs are not modified. But all requests are sent in developer mode to http://localhost:3000 (base URL) - that means the complete url login url is http://localhost:3000/auth/login. – CapCa Mar 08 '16 at 13:02
  • And localhost:3000 is reachable from your device? – Thierry Templier Mar 08 '16 at 13:14
  • Oh, dear, now you noticed my manipulation - I am testing in a local network and replace the localhost with an ip address. And yes, it is reachable. Sorry I tried to hide data due to privacy reasons and therefore I made this mistake in my answer. – CapCa Mar 08 '16 at 13:20
  • I asked for this because when you receive such error it's because the onerror callback of xhr is called. But it's not really possible to get the actual error. See this question: http://stackoverflow.com/questions/35669087/get-error-message-from-angular-2-http/35670089#35670089. – Thierry Templier Mar 08 '16 at 13:24
  • 1
    You are right, somehow Android Chrome did not accept my certificate but after some time everything works find. Amazing. But thank you very much for your help! :) – CapCa Mar 08 '16 at 14:22

1 Answers1

-1

Remove the webkit plugin from ios project and it will start working.

Milo
  • 3,365
  • 9
  • 30
  • 44
Amit Rai
  • 1
  • 1
  • 1
  • 1