web-dev-qa-db-ja.com

AngularユーザーがブラウザタブでURLを手動で変更したときのルーティングを防止する

ユーザーがブラウザーのタブでルートを手動で変更してEnterキーを押すと発生する問題で立ち往生しています。これにより、ユーザーが入力した状態にui-router/angular2-routerが強制的にナビゲートされます。これを防ぎ、自分のWebサイトのボタンクリックで実装したフローを介したルーティングのみを許可します。

13
Vishal Gulati

その2018! Angular 5がここにあり、これがこの問題の解決策です。BAMMそのCanActivateルートがアクティブ化できるかどうかを決定するガードとしてクラスが実装できるインターフェイス。

この機能を追加して、定義した条件に基づいて一部のルートへのアクセスを禁止できます。 CanActivateインターフェイスを実装し、canActivateメソッドを定義するAuthGuardなどのサービスをルート構成に追加できます。

class Permissions {
  canGoToRoute(user: UserToken, id: string): boolean {
    return true;
  }
}

@Injectable()
class AuthGuard implements CanActivate {
  constructor(private permissions: Permissions, private currentUser: UserToken) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    return this.permissions.canGoToRoute(this.currentUser, route.params.id);
  }
}

アクセスをある条件から保護したいルートがある場合は、次のようにガードを追加します。

const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  {
    path: 'heroes',
    canActivate: [AuthGuard],
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundComponent }
];

ここで、ルートheroesとそのすべての子には、その上にガード層があります。したがって、AuthGuardサービスによって返されるブール値に基づいて、ユーザーはこのルートへのアクセスを許可または拒否されます。

7
Vishal Gulati

ガードのコンストラクターにルーターをインポートできます。このルーターインスタンスには現在のURLが含まれます。 canActivateのActivatedRouteSnapshotおよびRouterStateSnapshotには、ユーザーがアクセスしようとしているURLが含まれます。

以下の例では、ユーザーが外部ページからルートに直接アクセスできないようにしています。

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class DirectAccessGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    // If the previous URL was blank, then the user is directly accessing this page
    if (this.router.url === '/') {
      this.router.navigate(['']); // Navigate away to some other page
      return false;
    }
    return true;
  }
}

このガードをルーティングモジュールに追加します

{ path: 'signup/:type/:step', component: SignupComponent, canActivate: [DirectAccessGuard] }
3
Scott Reed

$stateChangeStartイベントはこれを処理する適切な場所です。このイベントは、URLに移動しようとすると発生します。その時点で、ユーザーが認証されているかどうかを確認でき、認証されていない場合は、バウンスしてログインし直します。

あなたはこのようなイベントをフックします:

angular
  .module('myApp')
  .run(function ($rootScope, $state, authFactory) {
    $rootScope.$on('$stateChangeStart', function () {
      //if user is not logged in
      if(!authFactory.isAuthed()){ 
        $state.go('login')
      }
    })
  });

それが役に立てば幸い。

0