Angular 5 not redirecting after login

Issue

I’m using Angular 5 to implement an authentication system that uses Tokens.

When I try to authenticate on the login-form it’s starts the authentication form but then it just refreshes the page:

Before login

After login

The server response

This is my project file structure:

src
├── app
│   ├── app.component.css
│   ├── app.component.html
│   ├── app.component.spec.ts
│   ├── app.component.ts
│   ├── app.module.ts
│   ├── auth
│   │   ├── auth.guard.spec.ts
│   │   ├── auth.guard.ts
│   │   ├── auth.service.spec.ts
│   │   ├── auth.service.ts
│   │   └── token.response.ts
│   ├── dashboard
│   │   ├── dashboard.component.css
│   │   ├── dashboard.component.html
│   │   ├── dashboard.component.spec.ts
│   │   └── dashboard.component.ts
│   ├── login-form
│   │   ├── login-form.component.css
│   │   ├── login-form.component.html
│   │   ├── login-form.component.spec.ts
│   │   └── login-form.component.ts
│   └── navbar
│       ├── navbar.component.css
│       ├── navbar.component.html
│       ├── navbar.component.spec.ts
│       └── navbar.component.ts

And these are the main project files:

app.component.html:

<router-outlet></router-outlet>

app.module.ts:

import { RouterModule, Routes } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { CookieService } from 'ngx-cookie-service';
import { HttpClient, HttpClientModule,
         HTTP_INTERCEPTORS } from '@angular/common/http';

import { AuthService } from './auth/auth.service';
import { AuthGuard } from './auth/auth.guard';
import { AppComponent } from './app.component';
import { LoginFormComponent } from './login-form/login-form.component';
import { NavbarComponent } from './navbar/navbar.component';
import { DashboardComponent } from './dashboard/dashboard.component';


const appRoutes:Routes = [
  {
    path: '',
    component: LoginFormComponent
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
  }
]


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    LoginFormComponent,
    DashboardComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    RouterModule.forRoot(appRoutes),
  ],
  providers: [
    AuthService,
    AuthGuard,
    CookieService,
    HttpClient,
    RouterModule,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

login-form.component.html:

<div class="container">
    <div class="card card-container">
        <p id="profile-name" class="profile-name-card">OneBets</p>
        <form class="form-signin" (submit)="loginUser($event)">
            <span id="reauth-email" class="reauth-email"></span>
            <input type="text" id="inputEmail" class="form-control" placeholder="User" required autofocus>
            <input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
            <button class="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button>
        </form>
        <a href="#" class="forgot-password">
            Forgot the password?
        </a>
    </div>
</div>

login-form.component.ts:

import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { AuthService } from '../auth/auth.service'

@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent implements OnInit {

  constructor(private auth:AuthService, private router: Router,
              private cookieService: CookieService,) { }

  ngOnInit() {
  }

  loginUser(e) {
    this.auth.removeTokens();

    this.auth.authenticate(e.target.elements[0].value,
                           e.target.elements[1].value).subscribe(
      (res) => {
        console.log('Data received.', res);
        this.auth.token = res['access'];
        this.cookieService.set('refreshToken', res['refresh']);
        console.log(this.auth.token);
        this.router.navigate(['dashboard']);
      },
      (err) => {
        window.alert("Error at login. Check user and password.");
        console.error(err);
      }
    );

  }
}

auth.service.ts:

import { Router } from '@angular/router';
import { Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs/Observable';
import { NgModule } from '@angular/core';
import { TokenResponse } from './token.response'

const httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};


@Injectable()
export class AuthService {

  constructor(
    private cookieService: CookieService, private http:HttpClient,
    private router: Router) { }

  get token() {
    if (this.cookieService.check('token')) {
      return('Bearer ' + this.cookieService.get('token'))
    }
    else {
      return null;
    }
  }

  set token(newToken) {
    this.cookieService.set('token', newToken)
  }

  getApiHttpOptions(token=false) {
      if (token) {
        console.log('headers are:', { 'Content-Type': 'application/json' });
        return { headers: new HttpHeaders(
          { 'Content-Type': 'application/json' }) }
      } else {
        console.log('headers are:', { 'Content-Type': 'application/json',
                                      'Authorization': this.token });

        return { headers: new HttpHeaders(
          { 'Content-Type': 'application/json',
            'Authorization': this.token }) }
      }
  }

  removeTokens() {
    console.log('Removing tokens.');
    if (this.cookieService.check('token')){
      this.cookieService.delete('token');
    }

    if (this.cookieService.check('refreshToken')){
      this.cookieService.delete('refreshToken');
    }

    return true;
  }

  get isLoggedIn() {
    // Check if there's a session token on the cookie
    if (this.cookieService.check('refreshToken')) {
      return true;
    } else {
      return false;
    }
  }

  authenticate(user, passwd) {
    console.log('Starting authentication');

    return this.http.post('/api/token/', {'username': user, 'password': passwd},
                          this.getApiHttpOptions(true))
  }
}

auth.guard.ts:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthService, private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    console.log('AuthGuard');

    if(this.auth.isLoggedIn) {
      return true;
    } else {
      window.alert("You don't have permission to view this page");
      this.router.navigate(['']);
      return false;
    }
  }
}

PS:

I’m just starting FrontEnd development and I’m trying to learn Angular 5.

I’ve already developed the authentication backend via Django Rest and I’m 100% sure that it is working.

Solution

In login-form.component.ts under loginUser, as the first line add: e.preventDefault().

The form is submitting a hard get request to the current url since you have a submit button.

Answered By – bc1105

Answer Checked By – Marie Seifert (AngularFixing Admin)

Leave a Reply

Your email address will not be published.