簡體   English   中英

Ionic 4 設置身份驗證時跳過登錄頁面

[英]Ionic 4 Skip login page when auth is set

我試圖在設置身份驗證時繞過登錄頁面。 一切正常,但只要設置了身份驗證,登錄頁面就會顯示不到半秒,然后重定向到所需頁面。 直接打開想要的頁面。 這是代碼片段。

App.component.ts

import { LoginserviceService } from './account/login/loginservice.service';
import { Router } from '@angular/router';
import { Component } from '@angular/core';

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { ScreenOrientation } from '@ionic-native/screen-orientation/ngx'


@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private authenticationService:LoginserviceService,
    private router:Router,
    private screenOrientation:ScreenOrientation,
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.screenOrientation.lock(this.screenOrientation.ORIENTATIONS.PORTRAIT)

      this.statusBar.styleDefault();
      this.splashScreen.hide();
      this.authenticationService.authenticationState.subscribe(state => {
        if (state) {
          this.router.navigate(['menu', 'dashboard']);
        } else {
          this.router.navigate(['firstpage']);
        }
      });

    });
  }
}

登錄服務Service.ts

import { Storage } from '@ionic/storage';
import { Injectable, OnInit } from '@angular/core';
import { HttpParams, HttpClient } from '@angular/common/http';
import { HTTP } from '@ionic-native/http/ngx';
import { BehaviorSubject } from 'rxjs';
import { Platform } from '@ionic/angular';

// import {ap} from 'rxjs/operator/map';
@Injectable({
  providedIn: 'root'
})
export class LoginserviceService {
  private login_URL = "some api call can't disclose.";
  // private login_URL = "http://localhost:8000";
  authenticationState = new BehaviorSubject(false);
  private storageKey = "email";
  constructor(
    private http:HTTP,
    private storage : Storage,
    private plt: Platform) { 
      this.plt.ready().then(() => {
        this.checkUserState();
      });
  } 
  loginApi(email:string,password:string)
  {
    return new Promise((resolve,reject)=>{
      this.http.post(this.login_URL,  

        { //params},
        {//headers}
      ).then(response => {

        let data = JSON.parse(response.data);

        if(data.error === "Success" && data.status === "200")
        {
          this.storage.set(this.storageKey, email).then(() => {
            this.authenticationState.next(true);
          });
          resolve("Success");
        }
        else if(data.error === "Email password does not match" && data.status === "209")
        {
            resolve(response.data.error);
        }
      })
      .catch(err => {
        reject(err);
      });
    })
  } 
  checkUserState()
  {
    this.storage.get("email")
    .then((data)=>{
      if(data !== null)
      // this.router.navigateByUrl('/menu/dashboard');
      this.authenticationState.next(true);
    })
  } 
  logout() {
    return this.storage.remove(this.storageKey).then(() => {
      this.authenticationState.next(false);
    });
  }
  isAuthenticated() {
    return this.authenticationState.value;
  }
}

授權守衛.ts

import { LoginserviceService } from './loginservice.service';


import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';


@Injectable({
  providedIn: 'root'
})
export class AuthguardService implements CanActivate {

  constructor(public auth: LoginserviceService) {}

  canActivate(): boolean {
    return this.auth.isAuthenticated();
  }
}

路由器

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', redirectTo: 'firstpage', pathMatch: 'full' },

  {
    path: 'menu',
    loadChildren: () => import('./menu/menu.module').then( m => m.MenuPageModule)
  },
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.module').then( m => m.DashboardPageModule)
  },
  {
    path: 'firstpage',
    loadChildren: () => import('./firstpage/firstpage.module').then( m => m.FirstpagePageModule)
  },
  {
    path: 'account',
    loadChildren: () => import('./account/account.module').then( m => m.AccountPageModule)
  },

];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

在你的服務中提供一個可觀察的值,而不是從主題最后發出的值。

  export class LoginserviceService {
      private login_URL = "some api call can't disclose.";
      private stateObs : Observable<boolean>;
      authenticationState = new BehaviorSubject(false);
      private storageKey = "email";
      constructor(
        private http:HTTP,
        private storage : Storage,
        private plt: Platform) { 
        this.stateObs = this.authenticationState.asObservable(); // provide an observable
          this.plt.ready().then(() => {
            this.checkUserState();
          });

      } 

      isAuthenticated() { // return obsvervable instead last emited value
        return this.stateObs;
      }
    }

在你的保護下

export class AuthguardService implements CanActivate {

  constructor(public auth: LoginserviceService, private router: Router) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    return this.auth.isAuthenticated().pipe(
      map(isAuth => {
        if (!isAuth) {
          return false; // or you can redirect to login page this.router.navigate(["/login"])
        } else {
          if (route.url === "login url") // authenticated user but trying to reach login page
          {
            return this.router.navigate(["/to-home-page"]);
          } else { // another page
            return true; //it's ok.
          }
        }
      }));
  }
}

通常應該總是有一個默認的重定向,例如默認可能是您的實際主頁(例如,如果用戶具有有效的身份驗證令牌 - 他們會立即直接轉到您的主頁,而如果他們沒有憑據,則“登錄' 頁面被加載,迫使用戶在進一步操作/使用之前登錄)

在您的用例中,您從一開始就有一個默認重定向將用戶定向到首頁,您可以嘗試刪除 routes 數組中的第一個默認重定向項,然后依靠 app.component 的構造函數來定義用戶應該去哪里。 這樣您就可以避免遇到的問題,但這不是最佳實踐:

const routes: Routes = [
  <!-- { path: '', redirectTo: 'firstpage', pathMatch: 'full' }, -->
  {
    path: 'menu',
    loadChildren: () => import('./menu/menu.module').then( m => m.MenuPageModule)
  },
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.module').then( m => m.DashboardPageModule)
  },
  {
    path: 'firstpage',
    loadChildren: () => import('./firstpage/firstpage.module').then( m => m.FirstpagePageModule)
  },
  {
    path: 'account',
    loadChildren: () => import('./account/account.module').then( m => m.AccountPageModule)
  },

];

我想分享我對這個問題的經驗。 我解決它試圖節省調用方法的時間。 不是在構造函數中調用檢查用戶狀態的方法,而是已經在檢查狀態以節省時間。 我用你的代碼舉了一個例子。

  constructor(
    private http: HTTP,
    private storage: Storage,
    private plt: Platform) {

    this.plt.ready().then(() => {
      this.storage.get("email").then((data) => {
        if (data !== null) {
          this.authenticationState.next(true);
        } else {
          this.authenticationState.next(false);
        }
      })


      this.checkUserState();
    });
  }

並在 app.component.ts 中添加一個 setTimeOut 作為幫助(一秒)。 我正在使用 navController 中的 navigateRoot 我在另一篇文章中看到了它。

setTimeout(() => {
this.authenticationService.authenticationState.subscribe(state => {
    if (state) {
      this.nav.navigateRoot(['menu', 'dashboard']);
      //this.router.navigate(['menu', 'dashboard']);
    } else {
      this.nav.navigateRoot(['firstpage']);
      //this.router.navigate(['firstpage']);
    }
  });
}, 1000);

你必須打電話給你的授權守衛 我給你一個例子,說明我如何使用 CanActivate

const routes: Routes = [  {
path:'firstpage',loadChildren()=>import('./firstpage/firstpage.module').then(m=>m.FirstpagePageModule), canActivate : [AuthGuardService] }];

其他一切都很好,這對我有用,對不起,我使用谷歌翻譯,希望對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM