![](/img/trans.png)
[英]Ionic 2 auth - Skip login page if there's an user on local storage
[英]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.