Angular redirect to login page Angular redirect to login page typescript typescript

Angular redirect to login page


Here's an updated example using Angular 4 (also compatible with Angular 5 - 8)

Routes with home route protected by AuthGuard

import { Routes, RouterModule } from '@angular/router';import { LoginComponent } from './login/index';import { HomeComponent } from './home/index';import { AuthGuard } from './_guards/index';const appRoutes: Routes = [    { path: 'login', component: LoginComponent },    // home route protected by auth guard    { path: '', component: HomeComponent, canActivate: [AuthGuard] },    // otherwise redirect to home    { path: '**', redirectTo: '' }];export const routing = RouterModule.forRoot(appRoutes);

AuthGuard redirects to login page if user isn't logged in

Updated to pass original url in query params to login page

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'], { queryParams: { returnUrl: state.url }});        return false;    }}

For the full example and working demo you can check out this post


Update: I've published a full skeleton Angular 2 project with OAuth2 integration on Github that shows the directive mentioned below in action.

One way to do that would be through the use of a directive. Unlike Angular 2 components, which are basically new HTML tags (with associated code) that you insert into your page, an attributive directive is an attribute that you put in a tag that causes some behavior to occur. Docs here.

The presence of your custom attribute causes things to happen to the component (or HTML element) that you placed the directive in. Consider this directive I use for my current Angular2/OAuth2 application:

import {Directive, OnDestroy} from 'angular2/core';import {AuthService} from '../services/auth.service';import {ROUTER_DIRECTIVES, Router, Location} from "angular2/router";@Directive({    selector: '[protected]'})export class ProtectedDirective implements OnDestroy {    private sub:any = null;    constructor(private authService:AuthService, private router:Router, private location:Location) {        if (!authService.isAuthenticated()) {            this.location.replaceState('/'); // clears browser history so they can't navigate with back button            this.router.navigate(['PublicPage']);        }        this.sub = this.authService.subscribe((val) => {            if (!val.authenticated) {                this.location.replaceState('/'); // clears browser history so they can't navigate with back button                this.router.navigate(['LoggedoutPage']); // tells them they've been logged out (somehow)            }        });    }    ngOnDestroy() {        if (this.sub != null) {            this.sub.unsubscribe();        }    }}

This makes use of an Authentication service I wrote to determine whether or not the user is already logged in and also subscribes to the authentication event so that it can kick a user out if he or she logs out or times out.

You could do the same thing. You'd create a directive like mine that checks for the presence of a necessary cookie or other state information that indicates that the user is authenticated. If they don't have those flags you are looking for, redirect the user to your main public page (like I do) or your OAuth2 server (or whatever). You would put that directive attribute on any component that needs to be protected. In this case, it might be called protected like in the directive I pasted above.

<members-only-info [protected]></members-only-info>

Then you would want to navigate/redirect the user to a login view within your app, and handle the authentication there. You'd have to change the current route to the one you wanted to do that. So in that case you'd use dependency injection to get a Router object in your directive's constructor() function and then use the navigate() method to send the user to your login page (as in my example above).

This assumes that you have a series of routes somewhere controlling a <router-outlet> tag that looks something like this, perhaps:

@RouteConfig([    {path: '/loggedout', name: 'LoggedoutPage', component: LoggedoutPageComponent, useAsDefault: true},    {path: '/public', name: 'PublicPage', component: PublicPageComponent},    {path: '/protected', name: 'ProtectedPage', component: ProtectedPageComponent}])

If, instead, you needed to redirect the user to an external URL, such as your OAuth2 server, then you would have your directive do something like the following:

window.location.href="https://myserver.com/oauth2/authorize?redirect_uri=http://myAppServer.com/myAngular2App/callback&response_type=code&client_id=clientId&scope=my_scope


Please, do not override Router Outlet! It's a nightmare with latest router release (3.0 beta).

Instead use the interfaces CanActivate and CanDeactivate and set the class as canActivate / canDeactivate in your route definition.

Like that:

{ path: '', component: Component, canActivate: [AuthGuard] },

Class:

@Injectable()export class AuthGuard implements CanActivate {    constructor(protected router: Router, protected authService: AuthService)    {    }    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {        if (state.url !== '/login' && !this.authService.isAuthenticated()) {            this.router.navigate(['/login']);            return false;        }        return true;    }}

See also:https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard