【问题标题】:Angular Routing callback path and auth0Angular 路由回调路径和 auth0
【发布时间】:2018-07-06 15:19:41
【问题描述】:

背景:

我正在尝试使用 Angular 应用程序,但在将头绕在路由上时遇到了很大的问题。

我有 2 个问题需要弄清楚,这几天我一直在努力解决这些问题,而此时,我只是在浪费时间兜圈子。

详情:

我在我的根应用模块中定义了一个路由树,如下所示:

export const ROUTES: Routes = [  
  { 
    path: "callback",  
    component: CallbackComponent
  },
  {
    path: "secure",
    loadChildren: "./secure/secure.module#SecureModule",
    canActivate: [AuthGuard]
  },  
  {
    path: "public",
    loadChildren: "./public/public.module#PublicModule"
  }, 
  {
    path: "",
    redirectTo: "public",    
    pathMatch: "full"
  },
  { path: "**", component: PageNotFoundComponent }
];

@NgModule({
  declarations: [AppComponent, PageNotFoundComponent],  
  imports: [    
    AuthModule,
    BrowserModule,
    BrowserAnimationsModule,    
    HttpClientModule,
    RouterModule.forRoot(ROUTES, {enableTracing: (environment.production === false)}),
    StoreModule.forRoot(reducers, { metaReducers }), //sets the entire app up to use ngrx store and applies the metaReducers class as a parent to all reducers used throughout the system. this helps with the debug tools
    EffectsModule.forRoot(effects),
    StoreRouterConnectingModule,
    environment.production === false ? StoreDevtoolsModule.instrument() : [],
  ],
  providers: [
    { provide: ErrorHandler, useClass: AppServices.RollbarErrorHandler },
    {
      provide: AppServices.RollbarService,
      useFactory: AppServices.rollbarFactory
    }
  ],
  exports: [AppComponent, PageNotFoundComponent]
})

当我第一次使用 URL localhost:4200 加载我的应用程序时,会加载公共路径。这对我来说很有意义,因为 URL 模式与“”路径匹配,因此它被重定向到“公共”路径并加载它。这工作正常,因为我的公共路径被正确加载。

当我针对 Auth0 进行身份验证时,我遇到的问题会在用户通过身份验证后调用定义为 localhost:4200/callback 的回调 URL。我认为这个 URL 与“回调”路由匹配,应该加载 CallbackComponent。不幸的是,它没有,它再次加载公共路径。

我的 CallbackComponent 是在我的 AuthModule (它也导出的地方)中定义的,这显然是一个单独的模块。在我的实验中,在 AppModule 页面中加载组件没有问题,所以我不认为这个组件在另一个模块中是一个问题,但我想我会提到它以防万一。

问题

1) 为什么当 URL 为 localhost:4200/callback 时“回调”路径没有加载?

2) Auth0 将在哈希后将令牌信息和任何错误传递回查询字符串中的同一 URL(例如 localhost:4200/callback#error=... 或者,成功时,localhost:4200/callback#access_token= ...)。这会对路径匹配产生影响吗?如果是这样,我应该更新我的路径以处理它?如果不是,我相信部分 URL 将被视为片段,所以我只是从 activateRoute 中获取该信息,或者我是否缺少其他方法来处理路由中的片段?

提前感谢您的帮助。

更新

我正在附加路由器跟踪块以显示我所看到的确切内容:

首先是导航到根 URL 时的导航事件

Navigated to http://localhost:4200/
platform-browser.js:380 Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 1, url: '/')
platform-browser.js:367 NavigationStart {id: 1, url: "/"}
platform-browser.js:380 Router Event: RouteConfigLoadStart
platform-browser.js:367 RouteConfigLoadStart(path: public)
platform-browser.js:367 RouteConfigLoadStart {route: {…}}
core.js:3675 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
platform-browser.js:380 Router Event: RouteConfigLoadEnd
platform-browser.js:367 RouteConfigLoadEnd(path: public)
platform-browser.js:367 RouteConfigLoadEnd {route: {…}}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 RoutesRecognized {id: 1, url: "/", urlAfterRedirects: "/public", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: NavigationCancel
platform-browser.js:367 NavigationCancel(id: 1, url: '/')
platform-browser.js:367 NavigationCancel {id: 1, url: "/", reason: ""}
platform-browser.js:380 Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 2, url: '/')
platform-browser.js:367 NavigationStart {id: 2, url: "/"}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 RoutesRecognized {id: 2, url: "/", urlAfterRedirects: "/public", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: GuardsCheckStart
platform-browser.js:367 GuardsCheckStart(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 GuardsCheckStart {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: 'public')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: 'public')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: '')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: '')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: GuardsCheckEnd
platform-browser.js:367 GuardsCheckEnd(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } , shouldActivate: true)
platform-browser.js:367 GuardsCheckEnd {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot, shouldActivate: true}
platform-browser.js:380 Router Event: ResolveStart
platform-browser.js:367 ResolveStart(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 ResolveStart {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ResolveEnd
platform-browser.js:367 ResolveEnd(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 ResolveEnd {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: '')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: '')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: 'public')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: 'public')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: NavigationEnd
platform-browser.js:367 NavigationEnd(id: 2, url: '/', urlAfterRedirects: '/public')
platform-browser.js:367 NavigationEnd {id: 2, url: "/", urlAfterRedirects: "/public"}

这是当我直接进入回调 url 时的路由器跟踪:

Navigated to http://localhost:4200/callback
platform-browser.js:380 Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 1, url: '/')
platform-browser.js:367 NavigationStart {id: 1, url: "/"}
platform-browser.js:380 Router Event: RouteConfigLoadStart
platform-browser.js:367 RouteConfigLoadStart(path: public)
platform-browser.js:367 RouteConfigLoadStart {route: {…}}
core.js:3675 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
platform-browser.js:380 Router Event: RouteConfigLoadEnd
platform-browser.js:367 RouteConfigLoadEnd(path: public)
platform-browser.js:367 RouteConfigLoadEnd {route: {…}}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 RoutesRecognized {id: 1, url: "/", urlAfterRedirects: "/public", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: NavigationCancel
platform-browser.js:367 NavigationCancel(id: 1, url: '/')
platform-browser.js:367 NavigationCancel {id: 1, url: "/", reason: ""}
platform-browser.js:380 Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 2, url: '/')
platform-browser.js:367 NavigationStart {id: 2, url: "/"}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 RoutesRecognized {id: 2, url: "/", urlAfterRedirects: "/public", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: GuardsCheckStart
platform-browser.js:367 GuardsCheckStart(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 GuardsCheckStart {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: 'public')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: 'public')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: '')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: '')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: GuardsCheckEnd
platform-browser.js:367 GuardsCheckEnd(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } , shouldActivate: true)
platform-browser.js:367 GuardsCheckEnd {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot, shouldActivate: true}
platform-browser.js:380 Router Event: ResolveStart
platform-browser.js:367 ResolveStart(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 ResolveStart {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ResolveEnd
platform-browser.js:367 ResolveEnd(id: 2, url: '/', urlAfterRedirects: '/public', state: Route(url:'', path:'') { Route(url:'public', path:'public') { Route(url:'', path:'') { Route(url:'', path:'') }  }  } )
platform-browser.js:367 ResolveEnd {id: 2, url: "/", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: '')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: '')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: 'public')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: 'public')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: NavigationEnd
platform-browser.js:367 NavigationEnd(id: 2, url: '/', urlAfterRedirects: '/public')
platform-browser.js:367 NavigationEnd {id: 2, url: "/", urlAfterRedirects: "/public"}

除了最初的 Navigated to value 之外,它基本上完全相同。

【问题讨论】:

  • 您能否发布您在浏览器开发工具中遇到的错误?以及您访问网址的方式?您是使用 routerlink 还是只是在浏览器搜索栏中输入?路径也区分大小写。
  • 没有错误。我在 RouterModule 上启用了跟踪,它根本没有说明回调路由。它直接跳转到空的默认路由。我尝试通过在浏览器栏中粘贴 url 来访问路由,但在实际使用中,Auth0 将在我需要解析的 url 之后使用一些哈希值调用 url 以获取用户信息以进行身份​​验证。
  • 当您输入任何其他非法路径时会发生什么?基本上它会转到找不到“**”路径组件的页面吗?
  • 实际上,即使在我放置了一个不存在的路径的情况下,它仍然会被重定向到公共路径。
  • 您可以尝试使用“”而不是“”吗?到目前为止,我觉得代码中的其他一切都很好。

标签: angular angular5 auth0 angular-router


【解决方案1】:

据我所见,有几件事可能是问题所在。

您应该使用“”而不是“”。 确保你有 index.html 路径的顺序也很重要。我认为你说得对。 我不确定它有多重要,但是您正在导出 ROUTES 而不是 routemodule。 尝试创建如下所示的路由模块:

const routes: Routes = [
  { path: 'callback', component: CallbackComponent },
  { path: 'secure', loadChildren: './public/public.module#SecureModule' },
  { path: 'public', loadChildren: './public/public.module#PublicModule' },
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: '**' , component: PageNotFoundComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

并将其导入您的应用模块。我也不确定你为什么要导出 appComponent,我虽然那里应该有 appmodule。

import { AppRoutingModule } from "./app-router.module";

@NgModule({
    declarations: [AppComponent, PageNotFoundComponent],  
    imports: [    
      AuthModule,
      BrowserModule,
      BrowserAnimationsModule,    
      HttpClientModule,
      AppRoutingModule,
      StoreModule.forRoot(reducers, { metaReducers }), //sets the entire app up to use ngrx store and applies the metaReducers class as a parent to all reducers used throughout the system. this helps with the debug tools
      EffectsModule.forRoot(effects),
      StoreRouterConnectingModule,
      environment.production === false ? StoreDevtoolsModule.instrument() : [],
    ],
    providers: [
      { provide: ErrorHandler, useClass: AppServices.RollbarErrorHandler },
      {
        provide: AppServices.RollbarService,
        useFactory: AppServices.rollbarFactory
      }
    ],
    exports: [AppComponent, PageNotFoundComponent]
  })

问题出在此处

在你们两个 routerTracing 中都得到了

platform-browser.js:367 NavigationStart(id: 1, url: '/')
platform-browser.js:367 NavigationStart {id: 1, url: "/"}

在第二个你应该得到

platform-browser.js:367 NavigationStart(id: 1, url: '/callback')
platform-browser.js:367 NavigationStart {id: 1, url: "/callback"}

关于你的第二个问题我认为你需要在路径中实现'callback:token'。检查Angular main guide 以及他们如何为英雄实现 id。但这对于tokens可能有所不同。

到目前为止,这就是我所得到的。祝你好运!如果您发布更新,我会尽力提供更多帮助。

【讨论】:

  • 如果 AppModule 是主应用模块并且没有中介共享模块,我认为 AppComponent 不应该在 AppModule 中导出,并且应该使用以下命令关闭模块:export class AppModule { }跨度>
  • 感谢您查看此内容。我将路由移到它自己的模块中(实际上我之前有这个,但如果出现问题,我将它移到主模块中),我将所有引号更改为单引号,我删除了导出属性(我最初有这个是因为我在一个 .NET 核心环境中,它有一个位于 AppModule 之上的浏览器模块。我已经使项目独立,因此不再需要导出)。不过还是没有运气。我什至不确定我现在应该寻找什么。
  • @JakeHova,除了您可以随意调整代码之外,您能否创建一些 plunker?
  • 我现在不在家,但是当我回来时,我会尝试在 plunkr 中重新创建它。如果有帮助的话,我正在使用 Angular CLI 1.6.5 和 angular 5.2.0。
  • 我意识到发生了什么。我在 .net 核心应用程序中有这个角度解决方案。核心应用程序本质上是一个外壳。我将其配置为将几乎所有内容都视为由 Angular 处理的路线。事实证明,早些时候我截获了回调调用,以便我可以将凭据拉入 .net 应用程序的会话,然后将其传递到我不再拥有的另一个 FE 页面。这就是为什么它一直回到根页面的原因。我将把它标记为答案,因为它提供了最多的信息,但真正的答案是我需要更加小心。
【解决方案2】:

仅用于扩展其他有效的 Vato 答案:

你的主应用模块应该像这样导出自己而不是它的组件:

import { whatever } from "anywhere";

@NgModule({
   declarations: [...],  
   imports: [...],
   providers: [...],
   exports: [...] // exporting no AppComponent here
})
export class AppModule {}  // exports self class after all

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多