I will tell you how I feel about authentication in my ionic application.
The first step is to create a view of the data you want to save. I used to store some user data and a jwt token for authentication.
user.ts:
export class AuthenticatedUser {
private _username: string;
private _id: number;
private _token: string;
public static GetNewInstance(): AuthenticatedUser {
return new AuthenticatedUser(null, null, null)
}
public static ParseFromObject(object): AuthenticatedUser {
const model = AuthenticatedUser.GetNewInstance();
if (object) {
model.username = object.username;
model.id = object.id;
model.token = object.token;
}
return model;
}
constructor(username: string, id: number, token: string) {
this._username = username;
this._id = id;
this._token = token;
}
get username(): string {
return this._username;
}
set username(value: string) {
this._username = value;
}
get id(): number {
return this._id;
}
set id(value: number) {
this._id = value;
}
get token(): string {
return this._token;
}
set token(value: string) {
this._token = value;
}
}
GetNewInstance AuthenticatedUser.ParseFromObject AuthenticatedUser . api object .
. - UserService. AuthenticatedUser . .
user.service.ts:
export class UsersService {
private _user: Subject<AuthenticatedUser> = new Subject<AuthenticatedUser>();
constructor(private storage: Storage) {}
public subscribeToUserService(callback) {
return this._user.subscribe(callback);
}
public updateUserService(user: AuthenticatedUser) {
this._user.next(user);
}
createOnStorage(user: AuthenticatedUser): Promise<AuthenticatedUser> {
return new Promise((resolve) => {
this.getOnStorage().then((res) => {
if (res) {
this.deleteOnStorage().then(() => {
});
}
}).then(() => {
this.updateUserService(user);
this.storage.set('user', JSON.stringify(user));
resolve();
});
});
}
getOnStorage(): Promise<AuthenticatedUser> {
return new Promise((resolve) => {
this.updateUserService(JSON.parse(this.storage.get('user')));
resolve(this.storage.get('user'));
});
}
getOnStorageSync() {
this.updateUserService(JSON.parse(this.storage.get('user')));
return this.storage.get('user');
}
updateOnStorage(user: AuthenticatedUser): Promise<AuthenticatedUser> {
return new Promise((resolve) => {
resolve(this.storage.get('user'));
});
}
deleteOnStorage(): Promise<AuthenticatedUser> {
return new Promise((resolve) => {
this.storage.clear();
resolve();
});
}
}
ApiService. HTTP . authenticatedUser.
@Injectable()
export class ApiService {
private baseUrl = "https://my.api.co";
private user: AuthenticatedUser;
constructor(private userService: UserService, private http: Http) {
getAuthUser()
}
private getAuthUser() {
this.userService.getOnStorage.then(
(user) => {
this.user = user;
});
}
private formatHeader(): RequestOptions {
const headers: Headers = new Headers();
if (this.user.token) {
headers.append('Authorization', 'Bearer ' + this.user.token);
}
return new RequestOptions({headers});
}
private handleBody(res: Response) {
return res.json() || {};
}
private handleError(error: Response | any) {
let errorModel: any = {};
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errorModel = { status: error.status, message: `${error.status} - ${err.cause} ` };
} else {
errorModel = { status: error.status, message: error.toString()};
}
return Observable.throw(errorModel);
}
putRequest(url: string, body: Object, auth: boolean = true): Observable<Object> {
let header = null;
if (auth) {
header = ApiService.formatHeader();
}
return this.http.put(this.BASE_URL + url, body, header)
.map(ApiService.handleBody)
.catch(ApiService.handleError);
}
postRequest(url: string, body: Object, auth: boolean = true): Observable<Object> {
let header = null;
if (auth) {
header = ApiService.formatHeader();
}
return this.http.post(this.BASE_URL + url, body, header)
.map(ApiService.handleBody)
.catch(ApiService.handleError);
}
headRequest(url: string, auth: boolean = true): Observable<Object> {
let header = null;
if (auth) {
header = ApiService.formatHeader();
}
return this.http.head(this.BASE_URL + url, header)
.map(ApiService.handleBody)
.catch(ApiService.handleError);
}
getRequest(url: string, auth: boolean = true): Observable<Object> {
let header = null
if(auth) {
header = ApiService.formatHeader();
}
return this.http.get(this.BASE_URL + url, header)
.map(ApiService.handleBody)
.catch(ApiService.handleError);
}
deleteRequest(url: string, auth: boolean = true): Observable<Object> {
let header = null;
if (auth) {
header = ApiService.formatHeader();
}
return this.http.delete(this.BASE_URL + url, header)
.map(ApiService.handleBody)
.catch(ApiService.handleError);
}
- AuthService. /.
auth.service.ts:
@Injectable()
export class AuthService {
private user: AuthenticatedUser;
constructor(private userService: userService, private apiService: ApiService) {
this.getAuthUser();
}
getAuthUser() {
this.userService.getOnStorage().then(
(user) => {
this.user = user;
}
);
}
login(email: string, password: string): Promise<AuthentificatedUser> {
return new Promise((resolve, reject) => {
this.apiService.postRequest('/auth', {email: email, password: password})
.subscribe(
res => resolve(AuthentificatedUser.ParseFromObject(res)),
error => reject(<any>error));
});
}
logout(): Promise<any> {
return new Promise((resolve) => {
this.userService.deleteOnStorage().then(() => {
resolve();
});
});
}
isLoggedIn() {
if (this.user.token) {
return true;
} else {
return false;
}
}
}
:
this.authService.login('login', 'password').then(
(user) => {
this.userSerivce.createOnStorage(user);
this.navCtrl.push(HomePage);
}).catch(
(err) => {
//show the error
}
);
, , , .
export HomePage() {
private user: AuthenticatedUser;
constructor(private userService: UserService) {
this.getAuthUser();
}
private getAuthUser() {
this.userService.getOnStorage().then(
(user) => {
this.user = user;
if (!this.user.token) {
this.navCtrl.push(LoginPage)
}
}
);
}
}