Team,
I have spent a few hours looking at this but can hardly understand why I am getting my expected results. Now I hate to waste time on stuffs, especially when I know you gurus are out there.
I have successfully implemented JWT tokens authentication on my server side application and can receive tokens on the mobile client. However, when I attached that token on the header and make a request to the server, the token does not get to the server, I can see that the token is attached to the header when I look at my logs files.
Here is the code that sends the request to my server API with attached header.
import { Component } from '@angular/core';
import { NavController, Loading, ModalController, Events } from 'ionic-angular';
import { AccountType, AccountStatus, TransactionStatus } from '../../models//enum';
import { TranslatePipe, TranslateService } from "ng2-translate/ng2-translate";
import { HelperService } from '../../providers/helperService';
import { AccountService } from '../../providers/accountService';
import { User, Account, Transaction, Data} from '../../models/domain';
import { ReloadPage } from '../reload/reload';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/retry';
@Component({
templateUrl: 'build/pages/accounts/accounts.html',
providers: [AccountService],
pipes: [TranslatePipe]
})
export class AccountsPage {
queryText: string;
accounts: Account[] = new Array<Account>();
userClaim: any;
constructor(
private nav: NavController,
private accountService: AccountService,
private modalController: ModalController,
private events: Events
) {
}
// ViewLoaded event
ionViewLoaded() {
this.accountService.getUserClaim()
.then((userClaim) => {
this.userClaim = userClaim;
this.getAccounts();
});
}
onclick() {
let reloadModal = this.modalController.create(ReloadPage);
reloadModal.present();
}
/**
* Gets all user accounts from the server and hand over transaction processing
* to processAccounts method.
*/
getAccounts() {
this.accountService.getAccounts(this.userClaim.user_id)
.map(res => res.json())
.subscribe(
data => {
this.accounts = data._embedded.accounts;
},
error => this.handleAccountProcessingError(error),
() => {
this.processAccounts(this.accounts);
});
}
/**
* Gets transactions for all user accounts from the server and hand over
* processing of transaction to sortTransactions method.
*/
processAccounts(accounts: Account[]) {
if (accounts != null) {
let transactions: Array<Transaction> = null;
accounts.forEach(account => {
this.accountService.getResource(account._links.transactions.href)
.map(res => res.json())
.subscribe(
data => {
transactions = data._embedded.transactions;
}, error => {
this.handleTransactionProcessingError(error)
}, () => {
this.sortTransactions(account, transactions);
});
});
}
}
/**
* Sort transaction list for an account into pending and posted accounts so for rendering
* on the view layer. If performance is an issue on the client the we may want to move
* this process to the server side code.
*/
sortTransactions(account: Account, transactions: Array<Transaction>) {
let posted: Array<Transaction> = Array<Transaction>();
let pending: Array<Transaction> = Array<Transaction>();
transactions.forEach(transaction => {
if (transaction.status == "PENDING") {
pending.push(transaction);
} else if (transaction.status == "POSTED") {
posted.push(transaction);
}
})
account.posted = posted;
account.pending = pending;
}
/**
* Logs error that may occur during account processing
*/
handleAccountProcessingError(error: any) {
console.log("An error occurred while processing user account data from the server " + error)
}
/**
* Logs error that may occur during transaction processing
*/
handleTransactionProcessingError(error: any) {
console.log("An error occurred while processing user account data from the server " + error)
}
}
The service class:
import { Injectable } from '@angular/core';
import { HelperService } from '../providers/helperService';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { JwtHelper } from 'angular2-jwt';
import { Storage, LocalStorage } from 'ionic-angular';
@Injectable()
export class AccountService {
private local: Storage;
private headers: Headers;
private jwtHelper: JwtHelper;
constructor(private http: Http) {
this.headers = new Headers();
this.local = new Storage(LocalStorage);
this.jwtHelper = new JwtHelper();
}
/**
* Fetches user canonical from the server side
* using unique username value stored in the token
*/
getUser(userId: string): Observable<Response> {
return this.getData(HelperService.BASE_URL_API + "/users/" + userId);
}
getAccounts(userId: string): Observable<Response> {
return this.getData(HelperService.BASE_URL_API + "/accounts/search/findByProfileUserId?id=" + userId);
}
getTransactions(accountId: string): Observable<Response> {
return this.getData(HelperService.BASE_URL_API + "/transactions/search/findByAccountId?id=" + accountId);
}
/**
* Fetches resource information from the server for a particular User
*/
getResource(resourceUrl: string): Observable<Response> {
return this.getData(resourceUrl);
}
patchTransaction(user: any): Observable<Response> {
return this.patchData(HelperService.BASE_URL_API + "/users/", user);
}
buildHeaders() {
let headers = new Headers({
'Accept': HelperService.CONTENT_TYPE.split(';')[0].replace("'", ""),
'Content-Type': HelperService.CONTENT_TYPE
});
return this.local.get(HelperService.AUTHORIZATION)
.then((token) => {
headers.append(HelperService.AUTHORIZATION, token);
console.log(headers);
return headers;
});
}
getData(url) {
return Observable
.fromPromise(this.buildHeaders())
.switchMap((headers) => this.http.get(url, new RequestOptions({ headers: headers })));
}
getUserClaim() {
return this.local.get(HelperService.AUTHORIZATION)
.then((token) => {
return this.jwtHelper.decodeToken(token);
});
}
patchData(url, data) {
return Observable
.fromPromise(this.buildHeaders())
.switchMap((headers) => this.http.patch(url, data, new RequestOptions({ headers: headers })));
}
putData(url, data) {
return Observable
.fromPromise(this.buildHeaders())
.switchMap((headers) => this.http.put(url, data, new RequestOptions({ headers: headers })));
}
}
The header information seen on my network tab of chrome browser developer tools for unsuccessful request where the custom header information does not reach the server.
Here is the logs on my server side code, I printed out header information to see if my custom header information reaches the server:
When I make the same request from postman the server side log looks like this:
Notice the content-type= application/json and x-auth-token = xxxxxxxxxxxxx
I know I am missing something but again I am new to ionic and angular world.
Thanks