简体   繁体   中英

Angular 5 not redirecting after login

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.

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.

I've also ran into the issue of the if condition skipping straight to the else, due to the method call not having () at the end of it.

if(this.auth.isLoggedIn) to if( this.auth.isLoggedIn() )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM