首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当auth卫队发送用户登录或注册时,角9和Ionic重定向到前一页

当auth卫队发送用户登录或注册时,角9和Ionic重定向到前一页
EN

Stack Overflow用户
提问于 2020-04-30 14:33:48
回答 1查看 856关注 0票数 0

我在开发一个应用程序。我有一个钢瓶页面,作为主页。当用户单击一个圆柱体大小以查看另一个页面中的详细信息时,我传递了一个动态路由。这个圆柱体详细页面有一个auth守卫,需要用户登录或注册。在成功登录或登录时,我希望用户返回到所选的圆柱尺寸详细信息页,它最初被重定向。我试着整合我在堆栈上看到的答案,但没有起作用。我希望我也能解释一下这件事是如何解决的。我会附上我的源代码。

auth.guard.ts

代码语言:javascript
复制
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

代码语言:javascript
复制
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保护。

代码语言:javascript
复制
<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

代码语言:javascript
复制
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 {}
EN

回答 1

Stack Overflow用户

发布于 2020-04-30 16:04:03

因此,对于您拥有的用例,在auth成功之后,您希望用户“恢复”到最初请求的页面,可以通过这种方式实现高层次的实现逻辑:

  • 在将用户重定向到auth页面时,需要捕获他们完整的“返回URL”并将其传递给用户,这样登录/ auth页面就可以访问它了。

如果您想坚持使用canLoad (这不仅阻止了对模块的访问,而且还阻止了模块的加载),有一种方法可以做到:

1.在导航到auth页面时更新canLoad方法以传递返回URL:

代码语言:javascript
复制
// **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服务之后,您将用户直接引导到先前尝试的页面:

代码语言:javascript
复制
// 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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61525867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档