Reputation: 13
I'm implementing the following tutorial in order to get some Angular basics: http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial
And in addition I actually want to use "angular2-jwt" library. But every GET or POST request I send with authHttp is failing with just an empty error in console if there is no JWT saved locally.
"Error: Error in login.component.html caused by:"
There is no "No JWT present or has expired" error text, nothing.
By the way, standard Http Class is working normally. And so is "tokenNotExpired()" method.
Also tried adding
'js-base64':'npm:js-base64/base64.js',
'buffer':'@empty'
to mapping information of my systemsjs.config.js, but still no result.
Got any ideas what am I doing wrong? :(
Angular 2.1.0 + angular2-jwt 0.1.25
app.module.ts
import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";
import {AppRoutingModule} from "./app-routing.module";
import {LoginComponent} from "./login/login.component";
import {MainComponent} from "./main/main.component";
import {AuthService} from "./services/auth.service";
import {AUTH_PROVIDERS} from "angular2-jwt";
@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpModule
],
declarations: [
AppComponent,
LoginComponent,
MainComponent
],
providers: [
AuthService,
AUTH_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule
{
}
login.component.ts
import { Component } from '@angular/core';
import { AuthService } from "../services/auth.service";
@Component({
moduleId: module.id,
templateUrl: 'login.component.html'
})
export class LoginComponent {
user: any = {
login: 'defaultLogin',
password: 'defaultPassword'
};
errorMsg = '';
constructor(
private authService: AuthService) { }
login() {
this.authService.login(this.user.name, this.user.password)
.subscribe(result => {
});
}
}
auth.service.ts
import {Injectable} from "@angular/core";
import {Response} from "@angular/http";
import "rxjs/add/operator/map";
import "rxjs/add/operator/toPromise";
import {AuthHttp} from "angular2-jwt";
@Injectable()
export class AuthService
{
constructor(private authHttp: AuthHttp)
{
}
login(username: string, password: string)
{
return this.authHttp.post('/api/login', JSON.stringify({username: username, password: password}))
.map((response: Response) =>{
return false;
});
}
}
Upvotes: 1
Views: 1750
Reputation: 22892
That's the default behaviour of angular2-jwt
By default, if there is no valid JWT saved,
AuthHttp
will return an Observable error with 'Invalid JWT'. If you would like to continue with an unauthenticated request instead, you can setnoJwtError
totrue
.
You should only use AuthHttp
when you want to do authenticated requests, so on your AuthService you also need to import the Http
service, something like this:
import { Injectable } from "@angular/core";
import { Http, Response} from "@angular/http";
import "rxjs/add/operator/map";
import "rxjs/add/operator/toPromise";
import { AuthHttp } from "angular2-jwt";
@Injectable()
export class AuthService
{
constructor(private http: Http, private authHttp: AuthHttp){ }
login(username: string, password: string){
//use this.http instead of this.authHttp
return this.http.post('/api/login', {username: username, password: password})
.map((response: Response) => {
return false;
});
}
}
As said before Angular2-jwt checks for a valid JWT token, if by any chances there isn't a valid JWT then it doesn't even do the request.
But if you want to use authHttp for every request you can disable the JWT token validation, by overriding the configs of the provider, on your app.modute.ts add it like this:
import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";
import {AppRoutingModule} from "./app-routing.module";
import {LoginComponent} from "./login/login.component";
import {MainComponent} from "./main/main.component";
import {AuthService} from "./services/auth.service";
import { provideAuth } from 'angular2-jwt';
@NgModule({
imports : [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpModule
],
declarations: [
AppComponent,
LoginComponent,
MainComponent
],
providers : [
AuthService,
provideAuth({
noJwtError: true,
})
],
bootstrap : [AppComponent]
})
export class AppModule
{
}
more info here
The AuthService with the error handler:
import { Injectable } from "@angular/core";
import { Http, Response} from "@angular/http";
import "rxjs/add/operator/map";
import "rxjs/add/operator/toPromise";
import { AuthHttp, AuthHttpError } from "angular2-jwt"; //we need to import the AuthHttpError
@Injectable()
export class AuthService
{
constructor(private http: Http, private authHttp: AuthHttp){ }
login(username: string, password: string){
//use this.http instead of this.authHttp
return this.http.post('/api/login', {username: username, password: password})
.map((response: Response) => {
return false;
})
.catch(this.handleError); // we had the catch
}
private handleError (error: Response | any) {
// In a real world app, we might use a remote logging infrastructure
let errMsg: string;
if (error instanceof AuthHttpError) {
//here we will handle JWT errors
console.log(error)
} else if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
}else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
Upvotes: 4