问题
I have routes like this:
const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
];
and AuthGuard
:
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private router: Router,
private authService: AuthService) { }
canActivate() {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['login']);
return false;
}
}
When the user visits the website, he gets redirected to the login page. Same happens when the user tries to access /dashboard
route without authentication. How can I redirect the user to /dashboard
if he's logged in? For example, when I visit myapp.com
and I'm logged in I want to be redirected to myapp.com/dashboard
.
回答1:
In this case I would probably redirect everything to DashboardComponent
using
{path: '', redirectTo: 'dashboard', pathMatch: 'full'}
and than the dashboard component can determinate if the user is logged in or not (as it has AuthGuard active), and if the user is not logged in it would redirect him to login.
回答2:
You want to look at resolve
property within the [Route
interface].
All of the following properties are available to a route:
export interface Route {
path?: string;
pathMatch?: string;
matcher?: UrlMatcher;
component?: Type<any>;
redirectTo?: string;
outlet?: string;
canActivate?: any[];
canActivateChild?: any[];
canDeactivate?: any[];
canLoad?: any[];
data?: Data;
resolve?: ResolveData;
children?: Routes;
loadChildren?: LoadChildren;
runGuardsAndResolvers?: RunGuardsAndResolvers;
_loadedConfig?: LoadedRouterConfig;
}
resolve
is designed to allow you to load some type of data before proceeding to the route. The signature for resolve
looks like this:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<T>|Promise<T>|T
We can ignore that signature however and simply override it because in this case we just want to redirect to /dashboard if the user is logged in. Otherwise display /login route normally.
The solution is to create an injectable
class and attach it to the login route's resolve
property.
@Injectable()
export class IsLoggedIn {
constructor(
private router: Router,
private authService: AuthService) {
}
resolve(): void {
if (this.authService.isAuthenticated) this.router.navigate(['/dashboard'])
}
}
On your /login route add the resolve property.
{
path: 'login',
component: LoginComponent,
resolve: [IsLoggedIn]
}
Now anytime a logged in user attempts to go to /login, they'll be redirected to /dashboard without seeing the login page.
回答3:
Probably the quickest thing to do is to tweak your LoginComponent
.
Given that this.authService.isLoggedIn()
returns a boolean. In your LoginComponent
you can quickly check the state in ngOnInit
as below:
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import {AuthService} from '<path_to_your_auth_service>';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
providers: []
})
export class LoginComponent implements OnInit {
constructor(
private _route: ActivatedRoute,
private _router: Router,
private _authService: AuthService
)
ngOnInit() {
// get return url from route parameters or default to '/'
this.returnUrl = this._route.snapshot.queryParams['returnUrl'] || '/';
// CHECK THE isLoggedIn STATE HERE
if (this._authService.isLoggedIn()) {
this._router.navigate([this.returnUrl]);
}
}
// Rest fo the logic here like login etc
login() { }
}
Note that you're only adding this to ngOnInit
if (this._authService.isLoggedIn()) {
this._router.navigate([this.returnUrl]);
}
来源:https://stackoverflow.com/questions/44121164/angular-2-redirect-if-user-is-logged-in