简体   繁体   中英

Angular lazy loaded module 401

I'm developing an angular app with multiple lazy loaded modules using angular cli. The resources (js, css and html) requires authorization which is set by a cookie. If the user is not signed in when loading the first page he will be redirected to a SSO log in page and then back to the app when successfully authorized. This flow is not something I can change.

The problem I have is that if the user loads one module, works in that module for a while and then leaves the page open but doesn't work with it more during the day. If the user then the next day starts with trying to load a route that requires another lazy module, that module will return a 401 since he no longer is authenticated. However, the user will not see that the module failed to load and feels like nothing happens.

I'm looking for a way to get notified when a lazy loaded module can't be loaded so I can redirect the user to the sign in page. Is this possible?

By using a PreloadingStrategy that preloads the lazyloaded modules this can be prevented since the application no longer needs to GET the specific module on route change when the user is no longer authenticated.

preload-strategy.ts (taken from John Papa repo link )

import { PreloadingStrategy, Route } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

export class PreloadSelectedModulesList implements PreloadingStrategy {
  preload(route: Route, load: Function): Observable<any> {
    return route.data && route.data['preload'] ? load() : of(null);
  }
}

app-routing.module.ts

import { PreloadSelectedModulesList } from './core/preload-strategy';
    const routes: Routes = [
        // Eagerly loaded
        { path: '', component: HomeComponent, pathMatch: 'full' },
        // Preloaded module
        { path: 'preloaded', loadChildren: './preloaded/preloaded.module#PreloadModule', data: {preload: true}},
        // Lazy loaded module
        { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule'}
    ];

@NgModule({
    imports: [
        RouterModule.forRoot(routes, {
            preloadingStrategy: PreloadSelectedModulesList
        })
    ],
    exports: [RouterModule],
    providers: [ PreloadSelectedModulesList, ..., ... ]
})

export class AppRoutingModule { }

There could still be a small edge-case where the user suddenly becomes unauthorized while trying to GET a module, in this case one workaround could be what Abris mentions above, extending Angulars ErrorHandler and checking thrown errors for module loading.

error-handler.ts

import { ErrorHandler } from '@angular/core';

export default class MyErrorHandler extends ErrorHandler {

 constructor() { 
   super();
 }

  handleError(error) {
      // Check and take appropriate actions
      ...
      // delegate to the default handler
      super.handleError(error); 

  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM