我在开发一个应用程序。我有一个钢瓶页面,作为主页。当用户单击一个圆柱体大小以查看另一个页面中的详细信息时,我传递了一个动态路由。这个圆柱体详细页面有一个auth守卫,需要用户登录或注册。在成功登录或登录时,我希望用户返回到所选的圆柱尺寸详细信息页,它最初被重定向。我试着整合我在堆栈上看到的答案,但没有起作用。我希望我也能解释一下这件事是如何解决的。我会附上我的源代码。
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
}
}auth.page.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保护。
<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>app-routing.module.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 {}发布于 2020-04-30 16:04:03
因此,对于您拥有的用例,在auth成功之后,您希望用户“恢复”到最初请求的页面,可以通过这种方式实现高层次的实现逻辑:
如果您想坚持使用canLoad (这不仅阻止了对模块的访问,而且还阻止了模块的加载),有一种方法可以做到:
1.在导航到auth页面时更新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.在您的auth服务中,在成功的auth服务之后,您将用户直接引导到先前尝试的页面:
// instead of this.router.navigateByUrl('/cylinders'), do ~this:
let returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/cylinders';
this.router.navigateByUrl(returnUrl)要使上面的工作正常工作,您需要导入ActivatedRoute等。
希望你能从这里拿下来。
也可以在这里看到类似的问题和答案:angular2: how to get Full path on CanLoad guard while maintaining redirect url
https://stackoverflow.com/questions/61525867
复制相似问题