首页 文章

使用Angular2,如何在登录重定向之前重定向到以前的URL

提问于
浏览
15

使用Angular2创建单个页面应用程序,我正在拦截未经身份验证的用户访问自定义 RouterOutlet 中的非公共路由并将其重定向到登录视图 . 成功登录后,我想将用户重定向到最初请求的视图,而不是默认视图 .

我注意到 Router 有一个 renavigate() 函数导航到最后一个成功的路由但是最后一个成功的路由是 /auth/login 而不是最初请求的url .

基本上:我如何访问或确定以前请求的URL?

我真的不想求助于传递查询字符串参数,除非我真的需要 . 理想情况下,作为 Router 组件的一部分访问 history 集合会很好,类似于 backbone.history

4 回答

  • 6
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    {
        // keep the attempted URL for redirecting
        this._loginService.redirectUrl = state.url;
    }
    
    • 使用Router成功进行身份验证时重定向到该URL(例如,在 login.component.ts 中) . 例如 . this._router.navigateByUrl(redirectUrl);

    附: @MichaelOryl和@Vitali的建议可行,但我的方式更符合Angular2最终版本 .

  • 4

    您可以在docs中找到 Location 类所需的内容 . back() 函数可能会为您完成 .

    另一种方法是订阅 Location 中的 popstate 事件 . MDN has docs谈论你可能会收到的 Value 观 .

    class MyCLass {
      constructor(private location: Location) {
        location.subscribe((val) => {
            // do something with the state that's passed in
        })
      }
    }
    

    否则,您可能需要一种跟踪路由器中的更改的服务,以便您可以访问它们 .

    class MyTrackingService {
      constructor(private router: Router) {
        router.subscribe((val) => {
            // store the routes here so that you can peel them off as needed?
        })
      }
    }
    

    在这种情况下,我正在访问 Router 对象并订阅任何更改,以便我可以跟踪它们 .

  • 3

    这对我有用 . 将它注入主App组件的构造函数中,并在bootstrap方法中注册它 . 页面加载的第一个 val 应该是原始URL . 我之后取消订阅是高效的,因为我(可能还)想要在此服务中监听后续路由器事件 . 将服务注入需要originalUrl的其他位置 .

    import { Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    import { Subscription } from 'rxjs/Subscription';
    
    @Injectable()
    export class UrlTrackingService {
    
      public originalUrl: string;
    
      constructor(
        private router: Router
      ) {
        let subscription: Subscription = this.router.events.subscribe((val) => {
          this.originalUrl = val.url;
          subscription.unsubscribe();
        });
      }
    
    }
    
  • 17

    Updated Example Using Angular 2.2.1

    将原始URL传递给登录组件的Auth Guard:

    import { Injectable } from '@angular/core';
    import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
    
        constructor(private router: Router) { }
    
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
            if (localStorage.getItem('currentUser')) {
                // logged in so return true
                return true;
            }
    
            // not logged in so redirect to login page with the return url
            this.router.navigate(['/login', { returnUrl: state.url }]);
            return false;
        }
    }
    
    import { Component, OnInit } from '@angular/core';
    import { Router, ActivatedRoute } from '@angular/router';
    
    import { AlertService, AuthenticationService } from '../_services/index';
    
    @Component({
        moduleId: module.id,
        templateUrl: 'login.component.html'
    })
    

    登录后重定向到上一个/原始URL的登录组件:

    export class LoginComponent implements OnInit {
        model: any = {};
        loading = false;
        returnUrl: string;
    
        constructor(
            private route: ActivatedRoute,
            private router: Router,
            private authenticationService: AuthenticationService,
            private alertService: AlertService) { }
    
        ngOnInit() {
            // reset login status
            this.authenticationService.logout();
    
            // get return url from route parameters or default to '/'
            this.returnUrl = this.route.snapshot.params['returnUrl'] || '/';
        }
    
        login() {
            this.loading = true;
            this.authenticationService.login(this.model.username, this.model.password)
                .subscribe(
                    data => {
                        // login successful so redirect to return url
                        this.router.navigate([this.returnUrl]);
                    },
                    error => {
                        // login failed so display error
                        this.alertService.error(error);
                        this.loading = false;
                    });
        }
    }
    

    有关更多详细信息和工作演示,您可以查看this post

相关问题