Angular angular2-jwt: Getting error using AuthHttp: JWT must have 3 parts

1.6k Views Asked by At

I am getting an error when I use the AuthHttp yet the authenticate returns a good token. And I verified it on https://jwt.io/ and it is good.

I am using Angular 4. My code is as following:

SignIn Code

 signIn(login: string, password: string) {
    this.UserLogin.name = login;
    this.UserLogin.password = password;

    this.http.post(this.baselink + '.json', this.UserLogin, { headers: contentHeaders })
      .subscribe(
      response => {
        localStorage.setItem('id_toke', response.json().token);
        this.jwt = localStorage.getItem('id_toke');
        this.decodedJwt = this.jwtHelper.decodeToken(this.jwt);
        this.userRole = this.decodedJwt.roles;
        console.log(this.userRole);
        this.useJwtHelper();
        this.router.navigate(['/']);
      },
      error => {
        console.log('Http Error ' + error.text());
        this.router.navigate(['http-error']);
      }
      );
  }

token![enter image description here]1:"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGVzIjpbInJlYWQtb25seSIsInJlYWQtd3JpdGUiXSwiaWF0IjoxNDk2MTkxNDg4LCJleHAiOjE0OTYyMDAwODh9.qPCQY3yHujuCLb9g-F5b0MUQO3tyTr_Y5YRoMOQ0DBA"

enter image description here

Yet get data is throwing error

   getPayments() {
       return this.authHttp.get(this.baselink + '/getPayments', { headers: contentHeaders })
            .map(
            (response: Response) => {
                const data = response.json();
                return data;
            }
            )
            .catch(
            (error: Response) => {
               console.log('Error getPayments: ' + error);
                return Observable.throw('Something went wrong: ' + error.text);
            }
            );
     }

and getting

Error getPayments: Error: JWT must have 3 parts

Having said that if I use return this.http.get(this.baselink + '/getPayments') instead it works. The connection of AuthHttp is not reaching the server. That specific controller is not restricted on the server for the time being but the intention is to secure it probably the token is not included in AuthHttp header

@NgModule({
    providers: [
        {
            provide: AuthHttp,
            useFactory: authHttpServiceFactory,
            deps: [Http, RequestOptions]
        }
    ]
})
export class AuthorizationModule { }


export function authHttpServiceFactory(http: Http, options: RequestOptions) {
    return new AuthHttp(new AuthConfig({
        headerName: 'Authorization',
        headerPrefix: 'bearer',
        tokenName: 'token',
        tokenGetter: (() => localStorage.getItem('id_token')),
        globalHeaders: [{ 'Content-Type': 'application/json' }],
        noJwtError: true
    }), http, options);
}

and global headers

export const contentHeaders = new Headers();
contentHeaders.append('Accept', 'application/json');
contentHeaders.append('Content-Type', 'application/json');
1

There are 1 best solutions below

0
On

I changed my function to the below

getPayments():  Observable<Payment[]> {
    // add authorization header with jwt token - mine is saved in authService service in jwt variable
    let headers = new Headers({ 'Authorization': 'Bearer ' + this.authService.jwt });
    let options = new RequestOptions({ headers: headers });


    return this.http.get(this.baselink + '/getPayments', options)
        .map((response: Response) => response.json())
        .catch(
        (error: Response) => {
            console.log(error);
            return Observable.throw('Something went wrong: ' + error.text);
        });
}

Now getting this error

function (encodingHint) {
        if (encodingHint === void 0) { encodingHint = 'legacy'; }
        if (this._body instanceof URLSearchParams) {
            return this._body.toString();
        }
        if (this._body instanceof ArrayBuffer) {
            switch (encodingHint) {
                case 'legacy':
                    return String.fromCharCode.apply(null, new Uint16Array(/** @type {?} */ (this._body)));
                case 'iso-8859':
                    return String.fromCharCode.apply(null, new Uint8Array(/** @type {?} */ (this._body)));
                default:
                    throw new Error("Invalid value for encodingHint: " + encodingHint);
            }
        }
        if (this._body == null) {
            return '';
        }
        if (typeof this._body === 'object') {
            return JSON.stringify(this._body, null, 2);
        }
        return this._body.toString();
    }

Checking the server side, the Authorization is missing!!

Update It is a server side cros issue. So apparently the browser will send 2 calls asking the server to allow that header and the server to approve it. In my case on the server side I needed to add my url to the FilterRegistraionBean. I had it added but not correctly