Nebular: Nebular Login not redirecting if already logged in

Created on 16 Nov 2018  路  7Comments  路  Source: akveo/nebular

Issue type

I'm submitting a ... (check one with "x")

  • [ ] bug report
  • [x] feature request

Issue description

Current behavior:
Login component not redirecting if already logged in. For example, you log in, you get redirected to some page, then if you go by url to Login again, you can login again, even if you did not log out and so on (the token is also still there)

Expected behavior:
Redirect to success redirect specified page if the user is authenticated

Steps to reproduce:
Login, and navigate again to login page and you will be able to login as many times as you wish

Related code:

NbAuthModule.forRoot({
      strategies: [
        NbPasswordAuthStrategy.setup({
          name: 'email',
          token: {
            class: NbAuthJWTToken,
            key: 'my_token'
          },
          baseEndpoint: environment.connectCoreUri,
          login: {
            endpoint: 'api/login',
            method: 'post',
            redirect: {
              success: 'auth/success',
              failure: null,
            },
          }
        }),
      ],
      forms: {},
    })

Other information:

npm, node, OS, Browser

Angular 6 all browsers

Angular, Nebular

Latest version of nebular
nice to have enhancement auth

Most helpful comment

@iosif-bancioiu You can definitely solve this by doing a check in your LoginComponent.

In my case, my LoginComponent is extending a class called NbLoginComponent. Thus, my check will be done in ngOnInit function. Here's how I do it:

import { Component, OnInit } from '@angular/core';
import { NbLoginComponent, NbAuthJWTToken } from '@nebular/auth';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss'],
})
export class LoginComponent extends NbLoginComponent implements OnInit {
  // no constructor

  ngOnInit() {
    this.service.onTokenChange().subscribe((token: NbAuthJWTToken) => {
      if (token.isValid()) {
        this.router.navigate(['pages/dashboard']); // Your redirection goes here
      }
    });
  }
}

Note that I don't have to inject anything in the constructor because the parent class (NbLoginComponent) already have everything I need. Hope this helps.

All 7 comments

Hi @iosif-bancioiu, this is not currently possible out of the box, so you would need to implement a custom route guard to track this and redirect.

Thanks, then i will untick the bug report and mark it as a feature request, maybe someday it will be available out of the box :)

@nnixaa one issue with this guard
code below
```
export class LoginGuardService implements CanActivate {
constructor(private authService: NbAuthService, private router: Router) {

}

canActivate() {
return this.authService.isAuthenticated()
.pipe(
tap(authenticated => {
if (authenticated) {
this.router.navigate(['auth/success']);
} else{
return true;
}
}),
);
}
```

If the user is not authenticated, return true is never hit, do you have any hints on this?

Thanks!

@iosif-bancioiu, I believe there is no need in the else clause, as you return the isAuthenticated observable to the code that calls canActivate, which in its turn returns Observable<boolean>, so true or false.

@iosif-bancioiu You can definitely solve this by doing a check in your LoginComponent.

In my case, my LoginComponent is extending a class called NbLoginComponent. Thus, my check will be done in ngOnInit function. Here's how I do it:

import { Component, OnInit } from '@angular/core';
import { NbLoginComponent, NbAuthJWTToken } from '@nebular/auth';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss'],
})
export class LoginComponent extends NbLoginComponent implements OnInit {
  // no constructor

  ngOnInit() {
    this.service.onTokenChange().subscribe((token: NbAuthJWTToken) => {
      if (token.isValid()) {
        this.router.navigate(['pages/dashboard']); // Your redirection goes here
      }
    });
  }
}

Note that I don't have to inject anything in the constructor because the parent class (NbLoginComponent) already have everything I need. Hope this helps.

please explain how to direct sucess to external url, like any other websites

@vikramsparamesh I found a workaround.

1) Login Component
```
export class LoginComponent extends NbLoginComponent implements OnInit {

ngOnInit() {
this.service.onTokenChange().subscribe((token: NbAuthJWTToken) => {
if (token.isValid()) {
this.router.navigate(['/auth/success']);
}
});
}

}

2) Auth Module Routing

{
path: 'success',
resolve: {
url: ExternalUrlProviderService,
skipLocationChange: true
},
canActivate: [AuthGuardService], //here do the regular authenticated check
component: AuthenticatedComponent, //empty component, (something to say redirecting maybe) you need a component here in order for the route to work
}

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers:[
{provide: ExternalUrlProviderService, //the service should exist but use value will define what to do in this case
useValue: () => {
const externalUrl = environment.URI; //the uri where to redirect if authenticated
window.open(externalUrl, '_self'); //open in self or new tab
},}
]
})
```

Was this page helpful?
0 / 5 - 0 ratings