App is going back to login page when pressing backbutton

Hi Everyone,

I am authenticating an app using token, in the app.component I have a condition to get “state” and redirect to home page or login page. If I log in and press backbutton, it is going to login page again. How to avoid this?
I looked at some structures showing how to build login and home page correctly in ionic 3, but I’m using ionic 4.

If I log in, even with the token authentication saved in storage, it is returning me the login page quickly before the home page.

What I really want to know is: How to avoid showing login page after sign in ? and how to remove it from the history back?

If anyone faced this issue, please, let me know!

2 Likes

Have you found any solution @Thiago.Lives ?

1 Like

You need to implement a canActivate guard on the login page that allows only non-authenticated users.

You could set a isLoggedIn variable on a AuthService that is checked by the guard. You would set it to true when the user is successfully logged in. This doesn’t solve the refresh problem, so the service constructor also contains a check and sets the variable to true if the user is logged in. An example with angularFire:

auth.service.ts

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';

@Injectable({ providedIn: 'root' })
export class AuthService {

    constructor(private afAuth: AngularFireAuth) {

        this.afAuth.authState.pipe(
            first())
            .subscribe(v => {
                if (v) this.isLoggedIn = true;
            });
    }

}

authstate.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRoute, UrlTree } from '@angular/router';

import { AuthService } from '[PATH TO SERVICE]';

@Injectable({ providedIn: 'root' })
export class AuthStateGuard implements CanActivate {
    constructor(private router: Router) { }

    canActivate(): boolean | UrlTree {

        console.log('AuthStateGuard has run');

        if (!this.auth.isLoggedIn) return true;

        return this.router.parseUrl('dash');
    }

}

app-routing.module.ts

import { AuthStateGuard } from '[PATH TO GUARD]';
...

...
{    
    path: 'login',
    canActivate: [AuthStateGuard],
    loadChildren: './login/login.module#LoginPageModule',
}
...

OR

A more concise version:

auth.service.ts

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';

@Injectable({ providedIn: 'root' })
export class AuthService {

    constructor(private afAuth: AngularFireAuth) { }

    // Pipe first value emitted and convert to promise
    isLoggedIn() {
        return this.afAuth.authState.pipe(first()).toPromise();
    }
}

authstate.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRoute, UrlTree } from '@angular/router';

import { AuthService } from '[PATH TO SERVICE]';

@Injectable({ providedIn: 'root' })
export class AuthStateGuard implements CanActivate {
    constructor(private router: Router) { }

    // async wraps function in a promise 
    // (angular will wait for promises and observables to complete; if they never complete the page will hang!)
    async canActivate(): Promise<boolean | UrlTree> {

        console.log('AuthStateGuard has run');

        // Call isLoggedIn method and await result. 
        // If false allow navigation to login page, else navigate to dash
        if (! await this.auth.isLoggedIn()) return true;

        return this.router.parseUrl('dash');
    }

}
1 Like

@AimaneBk yes! Sorry for late reply! The problem was the organization of the routers. We had to change it and add some routers as child.Even with AuthGuard, this problem was happening. It was a quick login screen showing even after logged (having token saved on storage).

@jaimax thank you for helping me. For now, the problem was solved. however, I’ll try your solution in another project.

Can you help by adding a code sample demonstrating how you implemented it?

Thanks in advance.