Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a problem in my angular project with the login component as it won't load the login page but instead it will show this:HTTP ERROR 401

When I try to log in using Postman, it works perfectly so I don't understand why does it have this behaviour since I don't get any error in the console or browser. login.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { LoginService } from '../services/login.service';
import { first } from 'rxjs/operators';
import {ToastrManager} from 'ng6-toastr-notifications';
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
loading = false;
submitted = false;
  constructor(private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private router: Router,
    private loginService: LoginService,
    public toast: ToastrManager, ) { }

  ngOnInit() {
    this.loginForm = this.formBuilder.group({
email: ['', Validators.required],
password: ['', Validators.required]
    });
  }
get loginFormControl() {return this.loginForm.controls; }
onSubmit() {
  this.submitted = true;

  // stop here if form is invalid
  if (this.loginForm.invalid) {
  return;
  }
  this.loading = true;
  this.loginService.login(this.loginFormControl.email.value, this.loginFormControl.password.value)
      .pipe(first())
      .subscribe(
        () => {
          this.toast.successToastr('Login succesfully');
          this.router.navigate(['/']);
        },
        () => {
          this.loading = false;
          this.toast.errorToastr('Something went wrong');
          this.loginForm.reset();
          this.loginForm.setErrors({
            invalidLogin: true
          });
        });

 }
}

login.service.ts:
import { Injectable } from '@angular/core';
import {Register} from '../Models/register';
import { HttpClient, HttpHeaders, HttpErrorResponse} from '@angular/common/http';
import { BehaviorSubject, Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
@Injectable({
  providedIn: 'root'
})
export class LoginService {
   httpOptions = { headers: new HttpHeaders(
    { 'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer',
    })
};
  userData = new BehaviorSubject<Register>(new Register());
ApiUrl = 'https://localhost:5001';
    constructor(private http: HttpClient, public router: Router) {
    }
    login(email, password) {
      return this.http.post<any>(this.ApiUrl + '/login/login', { email, password}, this.httpOptions
     )
      .pipe(map(response => {
        localStorage.setItem('authToken', response.token);
        this.setUserDetails();
        return response;
      }));
    }
    GetById(id) {
      return this.http.post(this.ApiUrl + '/register/' + id , this.httpOptions);
    }
    doLogout() {
      const removeToken = localStorage.removeItem('access_token');
      if (removeToken == null) {
        this.router.navigate(['/login']);
      }
    }

    // User profile
    setUserDetails() {
      if (localStorage.getItem('authToken')) {
        const userDetails = new Register();
        const decodeUserDetails = JSON.parse(window.atob(localStorage.getItem('authToken').split('.')[1]));
        userDetails.email = decodeUserDetails.sub;
        userDetails.name = decodeUserDetails.name;
        userDetails.isLoggedIn = true;
        userDetails.role = decodeUserDetails.role;
        this.userData.next(userDetails);
      }
    }

    handleError(error: HttpErrorResponse) {
      let msg = '';
      if (error.error instanceof ErrorEvent) {
        // client-side error
        msg = error.error.message;
      } else {
        // server-side error
        msg = `Error Code: ${error.status}\nMessage: ${error.message}`;
      }
      return throwError(msg);
    }
}

login.component.html:
<div class="col-md-6 offset-md-3 mt-5">    
    <div *ngIf="loginForm.errors?.invalidLogin" class="alert alert-danger mt-3 mb-0">    
      Email or Password is incorrect.    
    </div>    
    <div class="card">  
      <div class="card-body">    
        <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">    
          <div class="form-group">    
            <label for="email">Email</label>    
            <input type="text" formControlName="email" class="form-control" autofocus    
              [ngClass]="{ 'is-invalid': submitted && loginFormControl.email.errors }" />    
            <div *ngIf="submitted && loginFormControl.email.errors" class="invalid-feedback">    
              <div *ngIf="loginFormControl.email.errors.required">Email is required</div>    
            </div>    
          </div>    
          <div class="form-group">    
            <label for="password">Password</label>    
            <input type="password" formControlName="password" class="form-control"   
              [ngClass]="{ 'is-invalid': submitted && loginFormControl.password.errors }" />    
            <div *ngIf="submitted && loginFormControl.password.errors" class="invalid-feedback">    
              <div *ngIf="loginFormControl.password.errors.required">Password is required</div>    
            </div>    
          </div>    
          <button [disabled]="loading" class="btn btn-primary">    
            <span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>    
            Login    
          </button>    
        </form>    
      </div>    
    </div>    
  </div>    

LoginController.cs:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using AnotherAP.Helpers;
using AnotherAP.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace AnotherAP.Controllers
{
    [EnableCors("CorsPolicy")]
    [Authorize]
    [ApiController]
    [Produces("application/json")]
    [Route("[controller]")]
    public class LoginController : ControllerBase
    {
        private readonly IConfiguration _config;
        private readonly DataContext _context;
        public LoginController(IConfiguration config,DataContext context)
        {
            _context = context;
            _config = config;
        }
      

        [AllowAnonymous]
        [HttpPost]
        [Route("login")]
        public IActionResult Login([FromBody] Register model)
        {
            IActionResult response = Unauthorized();
            Register user = AuthenticateUser(model.Email,model.Password);
            if (user != null)
            {
                var tokenString = GenerateJWT(user);
                response = Ok(new
                {
                    token = tokenString,
                    userDetails = user,
                });
            }
            return response;
        }

       string GenerateJWT(Register user)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:SecretKey"]));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                new Claim("Name", user.Name.ToString()),
                new Claim("role",user.Role),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            };

            var token = new JwtSecurityToken(
                issuer: _config["Jwt:Issuer"],
                audience: _config["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(30),
                signingCredentials: credentials
            );
            return new JwtSecurityTokenHandler().WriteToken(token);
        }

      public  Register AuthenticateUser(string email,string password)
        {
            if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))
                return null;

            var user = _context.register.FirstOrDefault(x => x.Email == email && x.Password==password);
           
            // check if username exists
            if (user == null)
                return null;
            return user;

        }
       
    }
}

This behaviour started happening after I modified the code in the controller for AutheticateUser() by using the data context instead of list declaration. Before that it would not recognise the credentials but the page was properly displayed, instead it would not work with Postman.Now it returns 200 Ok with Postman, but the page will not load.Did anyone encounter a similar problem and might know the cause?Any help would be appreciated!Best regards!

What I have tried:

I have tried to set the headers locally in login.service.ts in login() method and declare the values email and password as strings.I also changed to a single value named user but without any luck as nothing changed.
Posted
Updated 16-Mar-20 9:03am
Comments
MadMyche 16-Mar-20 16:44pm    
Is this the same page/api call you were having problems with 5 days ago:
https://www.codeproject.com/Questions/5261957/405-error-method-not-allowed-for-POST-in-angular-p

1 solution

401 Error is an authorization failure: 401 Unauthorized - HTTP | MDN[^] - something you are trying to access requires a logged in user and you aren't providing one.

Normally, this happens on login code when you move it to a folder that has a web.config requiring a logged in user, or change the web.config file for a folder to one that needs authorisation.

So check your website installation (via FTP if necessary) and find out what you have done - we can't do anything about that for you!
 
Share this answer
 
Comments
MadMyche 16-Mar-20 16:45pm    
I think this poster was getting a 405 error on this last week
https://www.codeproject.com/Questions/5261957/405-error-method-not-allowed-for-POST-in-angular-p

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900