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:
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)