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