2015-12-31 5 views
15

Angular2を使用して1つのページアプリケーションを作成すると、カスタムのの非公開ルートへの認証されていないユーザーアクセスを傍受し、ログインビューにリダイレクトします。ログインに成功した後は、デフォルトのビューではなく、最初に要求されたビューにリダイレクトします。Angular2を使用すると、ログインリダイレクトの前のURLにリダイレクトする方法

私はRouterが最後に成功したルートをナビゲートするが、最後に成功した経路は/auth/loginではなく、もともと要求されたURLだったrenavigate()機能を持っていることに気付きました。

基本的に:以前にリクエストされたURLにアクセスする方法、またはこれを特定するにはどうすればよいですか?

実際には必要ない限り、クエリ文字列パラメータを渡すことに本当に訴えたくありません。理想的にはbackbone.historyに似たRouterコンポーネントの一部としてhistoryコレクションにアクセスすることは理想的です。

+0

'location.back()'はどうですか? –

答えて

16
  1. 使用認証ガード(CanActivateを実装します)。例を含むofficial documentationthis blogを参照してください。
  2. 認証ガードでRouterStateSnapshotを使用すると、要求されたURLを取得できます。

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    { 
        // keep the attempted URL for redirecting 
        this._loginService.redirectUrl = state.url; 
    } 
    
  3. (例えばlogin.component.tsで)Routerを用いて成功した認証にそのURLへのリダイレクト。例えば。 this._router.navigateByUrl(redirectUrl);

P.S. @MichaelOrylと@Vitaliの提案はうまくいくかもしれませんが、私のやり方はAngular2の最終リリースにもっと揃っています。

+1

' state.url'には実際にはユーザが入力したURL全体が含まれているわけではなく、保護されている状態を指すURLが含まれています。したがって、(1)このメソッドは保護された状態の子にリダイレクトされず、(2)補助ルートはURLから削除されます。 – Isaac

+0

@JonathanMiles説明はかなり前方に見えますが、私は従いません。私は '_loginServie'の作成方法を理解していません。 –

+1

@AaronC、ログインサービスの作成は問題の範囲外です。適切な方向を示すために、[サービスに関する公式チュートリアル](https://angular.io/docs/ts/latest/tutorial/toh-pt4.html)といくつかの例を参照してください:[Auth0から] (https://auth0.com/blog/angular-2-authentication/)と[Jason Watmoreから](http://jasonwatmore.com/post/2016/09/29/angular-2-user-registration-and -login-example-tutorial) –

6

Locationクラスのdocsで必要なものを見つけることができます。 back()関数がそれを実行する可能性があります。

もう1つの方法は、Locationpopstateイベントにサブスクライブすることです。 MDN has docsあなたが受け取ることが期待できる値について話しています。

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オブジェクトにアクセスし、私は彼らを追跡することができるように、すべての変更に加入しています。

+0

ご回答いただきありがとうございます。これは1つの選択肢です。理想的には私はAngular2のベストプラクティスを探していますが、まだベータであり、変更する可能性があることに感謝しています。私は、場所> PlatformLocationに履歴コレクションが含まれていることに気付きましたが、有効な方法ではなく、ルータとのやりとりができません。これは私の好みの方法であり、Angular2はアプリをナビゲートするのに推奨される方法です。 –

4

これは私のために働いた。あなたのメインのAppコンポーネントのコンストラクタに、ブートストラップメソッドでそれを登録した状態でそれを挿入します。 ページの最初の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(); 
    }); 
    } 

} 
+0

このコンポーネントの使い方を教えてください。 – Pradeep

+0

'bootstrap'メソッドでこのサービスを追加すると、他のコンポーネントやサービスでこのサービスを使用できます。 'bootstrap(AppComponent、[...、OriginalUrlService、...])。catch(err => console.error(err)); ' 他のサービス(httpなど)と同じようにこのサービスを注入し、' originalUrl'プロパティを使用して必要に応じてルータのリダイレクトを実行します。独自のコンポーネントやサービスに追加します: ' コンストラクタ( 民間のOU:OriginalUrlService、 民間ルータ:ルータ ){...} プライベートのsomeMethod():無効{ this.router.navigateByUrl(this.ous。 originalUrl); } ' –

3

角度2.2を使用して更新された例。コンポーネントにログインするために、元のURLを渡す1

認証ガード:

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

関連する問題