Login using Laravel Passport [Ionic 4]

Hi guys,

I have a slight problem with login, although the login script is working and communicating with Laravel Passport I can see the Bearer auth token etc, but the script doesn’t then redirect to the dashboard even though I have specified this.

I guess this is something really simple I’ve missed or mis-understood, sorry Ionic newbie here…
So I have

if (isAuthenticated) {
        this.presentToast("Success! You are now logged in");
        this.navCtrl.navigateForward('/dashboard'); // My understanding if authenticated then redirect to dashboard page???
      }

Here’s the full code

import { Component, OnInit } from '@angular/core';
import { NavController } from '@ionic/angular';
import { AuthProvider } from '../../../../providers/auth/auth';
import { Toast } from '@ionic-native/toast/ngx';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
  
  loading: any;
  formLogin: any = {
    email: '',
    password: '',
  };

  constructor(
    public authService: AuthProvider,
    private navCtrl: NavController, 
    public toast: Toast,
  ) { }

  ngOnInit() {
    
  }


  async checkAuthenticated() {
    try {
      let isAuthenticated = await this.authService.checkIsAuthenticated();
      if (isAuthenticated) {
        this.presentToast("Success! You are now logged in");
        this.navCtrl.navigateForward('/dashboard');
      }
    } catch (err) {
      this.presentToast('Error on verify authentication info');

    }
  }

  login(data: any) {
    this.authService.login(data)
      .then((response: any) => {
        this.presentToast("Checking Credentials");
        this.authService.storeCredentials(response);
        setTimeout(() => {
          this.checkAuthenticated()
        }, 750);
      })
      .catch(err => {
        this.presentToast('Error');
        if (err.status == 400) {
          this.presentToast("Please check you have entered your email and password!");
        } else if (err.status == 401) {
          this.presentToast("401 Error");
        } else {
          console.log(err.error.message);
          this.presentToast(err.error);
        }
        
      })
  }

  presentToast(msg: string) {
    this.toast.show(msg, '5000', 'top').subscribe(
      toast => {
        // console.log(toast);
      }
    );
  }

}

Anyone, please I could really use some of you awesome people’s help here, please!

Is there no-one that as encountered this?

There’s not really enough information to go on here, this should be fine:

    try {
      let isAuthenticated = await this.authService.checkIsAuthenticated();
      if (isAuthenticated) {
        this.presentToast("Success! You are now logged in");
        this.navCtrl.navigateForward('/dashboard');
      }
    } catch (err) {
      this.presentToast('Error on verify authentication info');

    }

But that depends on what isAuthenticated is evaluating to - it would be useful to see what this.authService.checkIsAuthenticated is actually doing.

Also, this is likely a bad idea:

        this.authService.storeCredentials(response);
        setTimeout(() => {
          this.checkAuthenticated()
        }, 750);

If you need to wait for storeCredentials to complete before running checkAuthenticated have it return a Promise and await it. Using setTimeout to deal with timing issues is a recipe for trouble, and it also results in an unnecessary baked in delay.

2 Likes

In addition to @joshmorony’s (typically) excellent advice, I would suggest complete avoidance of using storage for in-app communication (which it smells like you are doing here). Storage should only be used for “message-in-a-bottle”-type communication with future runs of the app, precisely for the reasons you are banging into here. It’s tedious and error-prone to require synchronization across stores and loads, and subjects the user to needless delay. It’s fine to stash authentication tokens in storage, but load them only on app startup. If you follow this rule, you never have to wait on storage writes.

1 Like

@joshmorony, @rapropos - This is my auth provider

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { Service } from '../../settings/Laravel';

@Injectable()
export class AuthProvider {

  isAuthenticated: boolean = false;

  constructor(public http: HttpClient, private storage: NativeStorage) {
  }

  async checkIsAuthenticated () 
  {
    let now = Date.now();
    let auth: any = await this.storage.getItem('auth')
    if (!!!auth)
      return false;
    if ( auth.expired_at <= now)
      return false;

    return true;
  }

  login (user: any) 
  {
    let request = {
      'grant_type': 'password',
      'client_id': Service.passport.client_id,
      'client_secret': Service.passport.client_secret,
      'username': user.email,
      'password': user.password,
    }

    return this.http.post(`${Service.url}/oauth/token`, request).toPromise();
  }

  register (user: any) 
  {
    return this.http.post(`${Service.apiUrl}/register`, user).toPromise();
  }

  removeCredentials () {
    this.storage.remove('auth');
  }

  storeCredentials (response: any) {
    let expired_at = (response.expires_in * 1000) + Date.now();

    this.storage.setItem('auth', {
      access_token: response.access_token,
      refresh_token: response.refresh_token,
      expired_at
    })
  }

}

Hope this may help you guys help me

I’ve since changed the auth guard, to not use native storage, but still unable to navigate to /dashboard upon successful login.

Assuming you aren’t getting any other errors, it seems likely that checkIsAuthenticated is returning false. Debug that method and see what values you are getting there (e.g. you could just do console.log(auth) inside of that method to see the value, and check that it is what you are expecting), if it’s not what you are expecting trace it back until you find the source of the problem.

@joshmorony - I did debug that and shows as true now I’ve removed the storage element. But still will not redirect to the dashboard page ??

What Toasts do you end up getting? Maybe that can give a hint