Angular 9和Ionic在auth-Guard发送用户登录或注册时重定向到上一页



我正在开发一个应用程序。我有一个圆柱体页面作为主页。当用户单击圆柱体大小以在另一个页面中查看其详细信息时,我传递了一个动态路由。这个Cylinder详细信息页面有一个身份验证保护,可以让用户登录或注册。成功登录或登录后,我希望用户返回到最初重定向的选定圆柱体大小详细信息页面。我试着把我在堆栈上看到的答案综合起来,但没有成功。我希望我也能解释一下它是如何解决的。我会附上我的源代码。

auth.guard.ts

import { Injectable } from '@angular/core';
import { CanLoad, Route, UrlSegment, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { take, tap, switchMap } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanLoad {
constructor(private authService: AuthService, private router: Router) {}
canLoad(
route: Route,
segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.userIsAuthenticated.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated) {
return this.authService.autoLogin();
} else {
return of(isAuthenticated);
}
}),
tap((isAuthenticated) => {
if (!isAuthenticated) {
this.router.navigateByUrl('/auth');
}
})
); // boolean
}
}

验证页面.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { NgForm } from '@angular/forms';
import { Observable } from 'rxjs';
import { LoadingController, AlertController } from '@ionic/angular';
import { AuthService, AuthResponseData } from './auth.service';
@Component({
selector: 'app-auth',
templateUrl: './auth.page.html',
styleUrls: ['./auth.page.scss'],
})
export class AuthPage implements OnInit {
// property
isLoading = false;
isLogin = true;
constructor(
private authService: AuthService,
private router: Router,
private loadingCtrl: LoadingController,
private alertCtrl: AlertController
) {}
ngOnInit() {}
authenticate(email: string, password: string) {
this.isLoading = true;
this.loadingCtrl
.create({ keyboardClose: true, message: 'Logging you in...' })
.then((loadingEl) => {
loadingEl.present();
let authObs: Observable<AuthResponseData>;
if (this.isLogin) {
authObs = this.authService.login(email, password);
} else {
// if we are not logged in but signing up
authObs = this.authService.signUp(email, password);
}
authObs.subscribe(
(resData) => {
console.log(resData);
this.isLoading = false;
loadingEl.dismiss();
this.router.navigateByUrl('/cylinders');
},
(errRes) => {
console.log(errRes);
loadingEl.dismiss();
const code = errRes.error.error.message;
let message = 'Could not sign you up, please try again';
if (code === 'EMAIL_EXISTS') {
message = 'This email address already exists!';
} else if (code === 'EMAIL_NOT_FOUND') {
message = 'E-Mail address could not be found.';
} else if (code === 'INVALID_PASSWORD') {
message = 'Your password is incorrect';
}
this.showAlert(message);
}
);
});
}
onSwitchAuthMode() {
this.isLogin = !this.isLogin;
}
// switch our authentication mode based on state. we invert. if its false its true if its true its false
onSubmit(form: NgForm) {
if (!form.valid) {
return;
}
// IF YOU HAVE A VALID FORM THEN WE MAKE A POSITIVE IF CHECK AND PROCEED TO THE BELOW
const email = form.value.email; // from the name given to our forms
const password = form.value.password;
// we check if authenticated and forward email and password
this.authenticate(email, password);
form.reset();
}
// SHOW ERROR MESSAGE TO USERS
private showAlert(message: string) {
this.alertCtrl
.create({
header: 'Authentication failed',
// tslint:disable-next-line: object-literal-shorthand
message: message,
buttons: ['Okay'],
})
.then((alertEl) => {
alertEl.present();
});
}
}

cylinders.page.html保存我的圆柱体列表,当用户单击该列表查看圆柱体的详细信息时,它会将用户带到圆柱体详细信息页面,但此圆柱体详细信息页具有auth-guard。

<ion-header>
<ion-toolbar>
<!-- HAMBURGER MENU BUTTON -->
<ion-buttons slot="start" contentId="main">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>Select Gas to Refill</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<!-- SUCCESSFUL LOGIN OR SIGNUP SHOULD TAKE USER TO THE SPECIFIED ROUTE BELOW  -->
<ion-item *ngFor="let cylinder of cylinders" [routerLink]="['./', cylinder.size]">
<ion-avatar slot="start">
<ion-img [src]="cylinder.imageUrl"></ion-img>
</ion-avatar>
<ion-label color="primary"> {{ cylinder.size }} </ion-label>
</ion-item>
</ion-list>
</ion-content>

应用程序路由模块.ts

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth/auth.guard';
const routes: Routes = [
{ path: '', redirectTo: 'cylinders', pathMatch: 'full' },
{
path: 'cylinders',
children: [
{
path: '',
loadChildren: () =>
import('./cylinders/cylinders.module').then(
m => m.CylindersPageModule
)
},
{
// BELOW IS THE DYNAMIC ROUTING WHEN USER SHOULD NAVIGATE AFTER AUTH
path: ':cylinderSize',
loadChildren: () =>
import('./cylinders/cylinder-detail/cylinder-detail.module').then(
m => m.CylinderDetailPageModule
),
canLoad: [AuthGuard]
}
]
},
{
path: 'auth',
loadChildren: () => import('./auth/auth.module').then(m => m.AuthPageModule)
},
{
path: 'checkout',
loadChildren: () => import('./checkout/checkout.module').then( m => m.CheckoutPageModule)
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}

因此,对于您所拥有的用例,您希望用户在验证成功后"恢复"到最初请求的页面,可以通过以下方式实现高级实现逻辑:

  • 在您的身份验证保护中,当将用户重定向到身份验证页面时,您需要捕获他们的完整"返回URL"并将其传递出去,以便登录/身份验证页面可以访问它。

  • 然后在成功的身份验证之后,您使用该返回URL并帮助用户导航到

如果你想坚持canLoad(这不仅阻止访问,还阻止加载模块(,有一种方法可以做到:

1.更新您的canLoad方法,以便在导航到身份验证页面时传递返回URL:

// **inside** canLoad guard obtain full path (returnURL) this way as suggested in this answer (segments is one of the arguments canLoad method receives): 
const returnUrl = segments.reduce((path, currentSegment) => {
return `${path}/${currentSegment.path}`;
}, '');

// then instead of this.router.navigateByUrl('/auth'), do ~this:
this.router.navigate(['auth'], { queryParams: { returnUrl: this.router.routerState.snapshot.url }});

2.现在在您的身份验证服务中,在成功的身份验证之后,您将用户引导到以前尝试的页面:

// instead of this.router.navigateByUrl('/cylinders'), do ~this:
let returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/cylinders';
this.router.navigateByUrl(returnUrl)

为了以上工作,你需要导入ActivatedRoute等

希望你能从这里拿走。

也可以在这里看到类似的问题和答案:angular2:如何在CanLoad guard上获得完整路径,同时维护重定向url

相关内容

  • 没有找到相关文章

最新更新