2016-10-20 11 views
0

私はhttp://www.localhost:4200/profilehttp://www.localhost:4200/editProfileというURLを持っています。両方のURLはログインしたユーザーに提供されます。今すぐ、アドレスバーにURLを直接入力してEnterキーを押すことではなく、利用可能なナビゲーションメニューからアクセシビリティを/editProfileにします。ユーザーがそうした場合、彼は/profileパスにリダイレクトされます。角2:URLのGETリクエストをブロックする

POSTを/editProfileに許可してもGETを行わないのと同じことがあります。

routesモジュールで利用できるCanActivateを使用して達成できますか?

おかげ

+0

ユーザーがナビゲーションメニューからそのルートに移動してもブラウザのアドレスバーからは直接移動しないとどうしてですか? – BeetleJuice

+0

ビジネス要件。 –

+0

第2に、これとは別に、それが使用されるかもしれない多くのそのようなシナリオがあります。たとえば、ショッピングカートの要約ページがある場合、チェックアウトページに行くことなくユーザーが直接訪問しないようにします。右? –

答えて

5

スミット。私はその問題を解決する方法は、ユーザーがアドレスバーを経由して移動するのを防ぐことではないので、目的を尋ねました。そうすることで、そのページへの正当なアクセス権を持っている必要があるユーザーのために機能が停止します。ユーザーが既にログインしている場合、なぜ彼女はedit profileページに直接アクセスできないのですか?また、ユーザーがブラウザ内で前後のナビゲーションボタンを使用しようとしたときに不具合が発生し、非常にイライラした経験をしています。

あなたはまだそれをしたい場合は...

あなたは

path: 'editProfile', 
component: EditProfileComponent, 
canActivate:[EditProfileGuard] 

EditProfileGuardあなたのルートの定義にCanActivateを使用することができますは、フラグがtrueに設定されている場合にのみナビゲーションを許可するサービスです

@Injectable() 
export class EditProfileGuard implements CanActivate { 

    //must be set to true for navigation to succeed 
    allow = false; 

    canActivate(){ 
     if(this.allow){ 
      this.allow = false; 
      return true; 
     } 
     else return false; 
    } 
} 

ユーザーがブラウザのアドレスバーからナビゲートすると、allowはfalseなのでアクセスが拒否されます。あなたは

import {EditProfileGuard} from '...' 
import {Router} from '@angular/router'; 
... 
export class MyComponent{ 

    constructor(private guard:EditProfileGuard, private router:Router){} 

    //execute this when link is clicked 
    goToProfile(){ 
     //so navigation will be allowed 
     this.guard.allow = true; 
     this.router.navigateByUrl('editProfile'); 
    } 
} 

があなたのAppModuleproviders配列にサービスを追加することを忘れないでください新しいルートに彼女を送信する前に

ユーザーがナビゲーションメニュー内のリンクをクリックすると、trueにallowを設定します。が

私は概要ページへcheckoutID必要なパラメータになるだろう、そのルート定義は、チェックアウトのページへのリンク(またはユーザーが保存したURL /summary/:id次のようになります。下のコメントに応えて

)にはidがあり、要約コンポーネントではその詳細情報を取得して表示するためにidを使用できます。

チェックアウトしていないユーザーが要約ページに直接移動しようとすると、idがなくなり、ナビゲーションが失敗します。要約コンポーネントのngOnInitにおいて

ユーザが偽idを発明し、移動しようとすると、Iコンポーネントをロードする代わりにリダイレクトすることができるように、私は、idを検証することになります。

これにより、正当なユーザーが直接ナビゲートしたり、ナビゲーションを仕事に進めることができます。

+0

答えてくれてありがとう@BeetleJuiceしかし、私が言及した第2のシナリオについては、あなたはガーランドを使ってそのようなルートをそれぞれ維持することに同意しますか? 2番目のシナリオ:ショッピングカートの概要ページがある場合、チェックアウトページに行くことなくユーザーが直接訪問しないようにします。 –

+0

私は、このページを参照用https://www.flipkart.com/viewcartとしてチェックすることをお勧めします。カートに商品を追加して買い物を続けると、カートには行かず、このリンクにアクセスしてみてください。https://www.flipkart.com/checkout/initそれはあなたに同じことを許可しません。これがより良い方法で説明されることを願っています –

+0

@SumitAgarwal私は自分の答えに段落を追加しました。あなたが私のアイデアを使用することを選択した場合は、その答えを選択しupvoteすることを忘れないでください。がんばろう。 – BeetleJuice

0

大きな回答@BeetleJuice。実際には、外部ルートイベントがアプリを再インスタンス化し、すべての変数(Angular Routing Gotchas)をクリアするという事実を利用することができます。

歩行く、あなたは "内部" ルーティングから抽象への第2のサービスを作成することができます

内部router.service.ts

import { Injectable } from '@angular/core'; 
import { Router, NavigationExtras, UrlTree } from '@angular/router'; 

@Injectable() 
export class InternalRouter { 

    private _isNavigationAllowed = false; 
    get isNavigationAllowed(): boolean { 
    return this._isNavigationAllowed; 
    } 

    constructor(private router: Router) { } 

    navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> { 
    return this.runNavigation(() => this.router.navigate(commands, extras)); 
    } 

    navigateByUrl(url: string | UrlTree): Promise<boolean> { 
    return this.runNavigation(() => this.router.navigateByUrl(url)); 
    } 

    private runNavigation(navigation:() => Promise<boolean>): Promise<boolean> { 
    this._isNavigationAllowed = true; 
    return navigation() 
     .then(success => { 
     this._isNavigationAllowed = false; 
     return Promise.resolve(success); 
     }) 
     .catch(e => { 
     this._isNavigationAllowed = false; 
     return Promise.reject(e); 
     }); 
    } 
} 

側内蔵only.guard.ts

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { InternalRouter } from './internal-router.service'; 

@Injectable() 
export class InternalOnlyGuard implements CanActivate { 

    constructor(private router: Router, private internalRouter: InternalRouter) { } 

    canActivate(): boolean { 
    if (!this.internalRouter.isNavigationAllowed) { 
     this.router.navigateByUrl('/'); // Or other logic 
     return false; 
    } 
    return true; 
    } 
} 

物事は注意する:

  • ガードは
  • ルーターサービスで
  • runNavigation()がかかる(、あなたのルートに応じて、リダイレクト、および他のガード)いくつかの状況で無限ループを避けるためにリダイレクト実際のルータを使用しています冷たい約束ですので、準備が整うまでルーティングを開始しません。

InternalRouterは、それ自身の状態について単独で責任を負うため、このアプローチがいいとわかりました。

関連する問題