82 thoughts to “Angular 8 JWT Auth – Token based Authentication with Web Api example”

  1. Hello, i have a problem if someone can help me,
    in the back-end i have this error : Error: Role is not found.
    because in the front-end we don’t specify the roles, for a simple user where i must add the role on the html singup form? or in ts file?
    for admin/moderator i added it manually but for a simple user how to do that from front-end form?

    1. register(user:User): Observable {
          return this.http.post(AUTH_API + 'signup', {
            username: user.username,
            email: user.email,
            password: user.password,
            role:['user']
          }, { responseType: 'text' });
        }
      
  2. Hi bezkoder,
    Thanks in advance for sharing your knowledge! Your tutorials are great.
    I got an error with angular front end part.(Spring boot backend works without any problem through postman).
    The error is it doesn’t load any part of UI.instead of that it comesup with this error.(I’m using angular 8)

    Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.
    at new PathLocationStrategy (common.js:782)
    at Object.provideLocationStrategy [as useFactory] (router.js:9875)
    at Object.factory (core.js:17376)
    at R3Injector.hydrate (core.js:17206)
    …………

    What should I update

  3. Hi bezkoder,
    I am not able to login successfully, there is no error come, when I saw in console network there is 204 status code return,
    please provide solution ,

  4. Hi,

    Yes, I have tested it with port 8081 without success

    OPTIONShttp://localhost:8080/api/v1/employees
    [HTTP/1.1 401 13ms]

    Solicitud de origen cruzado bloqueada: La política de mismo origen (Same Origin Policy) no permite la lectura de recursos remotos en http://localhost:8080/api/v1/employees. (Motivo: La respuesta CORS no tuvo éxito).

  5. I am a beginner to angular and spring boot. Can any one please help me to understand how the role is assigned to any new user (admin/mod/user) while registeration.

    register(user): Observable {
    return this.http.post(AUTH_API + ‘signup’, {
    username: user.username,
    email: user.email,
    password: user.password
    }, httpOptions);
    }

    I didn’t found any roles array int the above code, how it is inserted.
    Thank You in advance

    1. Hi, it is inserted by default in backend.

      If you want to set roles manually, you can add roles/role array in the Post request body.

      1. Hi,

        we need help with the CORS. We still can’t solve the problem. We still can’t solve the problem API calls

  6. i do the same your code at front end, but front end style is not the same like your images on Signup and Login. Mine were a wide range. Is there something wrong or not? can u guide me some?
    Thank you for your code.

    1. Hi, you can check .css files on Github source code, and don’t forget to import Bootstrap in index.html 🙂

      1. Thank you, bez. I forgot to check the css file. using the styl file. Now it’s ok for front end.

  7. hello and thank you for this tutorial
    I have a problem,
    property ‘getAdminBoard’ does not exist on type ‘AuthService’
    and it’s the same message for ‘getUserBoard’ and ‘getModeratorBoard’ that’s what! do I have to declare this property in my service as constant?

  8. Hello, Congratulations and thanks for sharing your work … But I have a problem. How could I make a post with the data of the logged in user ???? For example, id, name + other attributes of another table that user has a relationship ???

  9. when make a call between angular and spring boot http://localhost:8081/register
    i got this error
    In the controller side
    @RestController @CrossOrigin(origins = “http://localhost:8081”)
    and application.properties server.port=8080
    In angular side
    const API_URL = ‘http://localhost:8080/api/auth/’;

    Access to XMLHttpRequest at ‘http://localhost:8080/api/auth/signup’ from origin ‘http://localhost:8081’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

  10. hi Bez,
    Thank you very much for your great tutorial. Loved it so much and learned a lot.
    However, I would like to mention that I somehow found a small problem in this line

    this.tokenStorage.saveToken(data.accessToken);

    for me the object data does not have a property called “accessToken”, but just “token”. That made the access to protected resources does not work at first.

    Thanks again and have a nice day.

    1. Hi, which backend server do you use? Spring Boot or Node.js?
      You should follow the instruction for modifying app/_helpers/auth.interceptor.js.

  11. I added a class to do CRUD, it works in the backend, when I authenticate I have the authorization to access, but in angularjs, it does not work maybe I have to add something in my code in angularjs

  12. Hello, thank you for this excellent tutorial .
    i have problems with the role based authentication, the angular signup form only reads the role(admin) passed in :

     Role.findOne({ name: "admin" }, (err, role) => {
            if (err) {
              res.status(500).send({ message: err });
              return;
            }
    

    And i don’t know how to set the payload role as an array ca you help me with that please ?
    Thnak you

  13. Thank for your response.

    ****** auth.service.ts ******

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    const AUTH_API = 'http://localhost:8080/api/auth/';
    
    const httpOptions = {
      headers: new HttpHeaders({ 'Content-Type': 'application/json' })
    };
    
    @Injectable({
      providedIn: 'root'
    })
    
    export class AuthService {
    
      constructor(private http: HttpClient) {}
    
      login(credentials): Observable {
        return this.http.post(AUTH_API + 'signin', {
          pseudo: credentials.pseudo,
          mdp: credentials.mdp
        }, httpOptions);
      }
    
      register(user): Observable {
        return this.http.post(AUTH_API + 'signup', {
          pseudo: user.pseudo,
          email: user.email,
          mdp: user.mdp,
          nom: user.nom,
          tel: user.tel,
          cin: user.cin,
          date_embauche: user.date_embauche,
          adresse: user.adresse,
          role: user.role,
        }, httpOptions);
      }
    }
    
      1. ******auth.controller.js ******

        const config = require("../config/auth.config");
        const db = require("../models");
        const User = db.user;
        const Role = db.role;
        
        var jwt = require("jsonwebtoken");
        var bcrypt = require("bcryptjs");
        
        exports.signup = (req, res) => {
          const user = new User({
            pseudo: req.body.pseudo,
            email: req.body.email,
            mdp: bcrypt.hashSync(req.body.mdp, 8),
            nom : req.body.nom,
            tel : req.body.tel,
            cin : req.body.cin,
            date_embauche : req.body.date_embauche,
            adresse : req.body.adresse
          });
        
          user.save((err, user) => {
            if (err) {
              res.status(500).send({ message: err });
              return;
            }
        
            if (req.body.roles) {
              Role.find(
                {
                  name: { $in: req.body.roles }
                },
                (err, roles) => {
                  if (err) {
                    res.status(500).send({ message: err });
                    return;
                  }
        
                  user.roles = roles.map(role => role._id);
                  user.save(err => {
                    if (err) {
                      res.status(500).send({ message: err });
                      return;
                    }
        
                    res.send({ message: "User was registered successfully!" });
                  });
                }
              );
            } else {
              Role.findOne({ name: "client" }, (err, role) => {
                if (err) {
                  res.status(500).send({ message: err });
                  return;
                }
        
                user.roles = [role._id];
                user.save(err => {
                  if (err) {
                    res.status(500).send({ message: err });
                    return;
                  }
        
                  res.send({ message: "User was registered successfully!" });
                });
              });
            }
          });
        };
        
        ...
        
        1. Check your database, in roles collection/table. Did it have role object with name=client?
          Role.findOne({ name: "client" }...)

          If not, you should follow the step of creating 3 roles in database.

          1. Yes i have a role object with name=client but the signup form in angular only read the client role even if i put admin role in the form ? I think i have to set the payload role is an array ? how can i fix it please ?

  14. Hi, thank you so much for this tutorial. I followed this one and the one for node.js backend but i got this error :

    TypeError: Cannot read property ‘_id’ of null
    at C:\Users\LDE\pfe20\backend\controllers\auth.controller.js:56:28

  15. Hello Bezkoder,
    thanks for your wonderful guides. I followed this one and the one for node.js backend and everything works great <3 !
    Since i would call me a beginner, i have problems with the protected components. Can i send html from backend: user.controller.js , or do i need a different way to send html that works together with component.ts ?

    Thank you in advance ! Greetings from Germany

    1. Hi, if you use Node.js Express:

      var html = fs.readFileSync('./html/test.html', 'utf8')
      res.render('test', { html: html })
      

      Or you can search google with keyword: server-side rendering.

      1. Thank you very much for your help. I dont think, that server-side rendering fits my project. Any tips for protecting existing routes with the JWT provided by your tutorials without using html from the server ?

        Thank you so much for your time !

  16. Hello! I try to add role in registration but it doesn’t work

    register(user): Observable {
        return this.http.post(AUTH_API + 'signup', {
          username: user.username,
          email: user.email,
          telephone: user.telephone,
          role: user.role,
          password: user.password
        }, httpOptions);
    
  17. thanks very much for this tutorail but i got this error with angular “error TS2306: File auth.interceptor.ts’ is not a module”

  18. Hello! Thank you a lot for sharing this tutorial it is very helpful, I have a question which is I added roles to register form so I had this error :

    Signup failed!
    Invalid JSON input: Cannot deserialize instance of `java.util.HashSet` out of VALUE_STRING token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.HashSet` out of VALUE_STRING token at [Source: (PushbackInputStream); line: 1, column: 79] (through reference chain: com.suivi.app.Model.RegistrationForm[“roles”])

    Even I didn’t add roles to the form, sign up failed and if you asking about register is it working on back end yeah it works. Please can you help me to solve this issue. And Than you.

  19. Hello, how can i assign a specific role when registering ? thank you, i try to input a role in register form but the set type doesn’t accept a string

    1. Hi, you need to transform the form data into JSON payload like this:

      {
      	"username": "user",
      	"email": "[email protected]",
      	"password": "12345678",
      	"roles": ["user", "mod"]
      }
      
  20. This is awesome, so beautifully described, thanks a lot!

    I finished this one and I’m working on adding canActivate() method so that it protects routes of admin and user.
    If you have done any blog on it or know any sources please attach them on the reply.

    Thanks a lot, you’re a life saver.

  21. Excuse me, I already installed it from the console and not from the ide VS.
    thanks anyway

  22. Hi, when you download the project and run ng serve …
    An unhandled exception occurred: Cannot find module ‘@angular/compiler-cli’
    I have Angular 8.3.23.
    I try npm install. but nothing, an error appears
    npm WARN saveError ENOENT: no such file or directory,…….

    1. Hi, you can try these steps:
      – update angular-cli to the latest version

      $ npm remove -g angular-cli
      $ npm install -g @angular/[email protected]
      

      – update the project dependencies

      $ rm -rf node_modules dist
      $ npm install --save-dev @angular/[email protected]
      $ npm install
      
  23. hi, please if you explain me this:

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

    thank you

  24. Hi, I’ve tried to make some modification in the register.component.html (to add another field), but I cannot see any of them after I run “ng serve”. Do you have any idea what I am doing wrong?

      1. I just tried to display another field “check password” [I just copy/paste/change a little bit the code used for password…in html]

  25. Bonjour,
    j’ai obtient le problème suivant
    Access to XMLHttpRequest at ‘http://localhost:8080/api/auth/signin’ from origin ‘http://localhost:4200’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

    Malgré que j’ai ajouté au niveau de l’api rest le code suivant;@CrossOrigin(origins = “http://localhost:4200” ,allowedHeaders = “*”,allowCredentials = “true”)
    Quelqu’un peut m’aider?

    1. Hi, the server you used configures CORS for port 8081, so you have to run this Angular client with command: ng serve --port 8081 instead.

  26. I’m getting a CORS error from having my REST API on api.domain.com and my Angular site on dev.domain.com . How do I allow the CORS between subdomains?

    Error:

    Access to XMLHttpRequest at ‘http://api.domain.com/auth/signup’ from origin ‘http://dev.domain.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The ‘Access-Control-Allow-Origin’ header has a value ‘http://api.domain.com/’ that is not equal to the supplied origin.

      1. I managed to figure it out, I want to be able to accept preflight and origin from all my subdomain and main domain so I setup a multi origin configuration. Might be useful as an addition for the article. Attaching below the reference.

        https://expressjs.com/en/resources/middleware/cors.html

        var whitelist = ['http://example1.com', 'http://example2.com']
        var corsOptions = {
          origin: function (origin, callback) {
            if (whitelist.indexOf(origin) !== -1) {
              callback(null, true)
            } else {
              callback(new Error('Not allowed by CORS'))
            }
          }
        }
        
  27. Hi,
    Thanks a lot for the helpful and beautiful tutorial. i have one question, i didn’t figure out where we put our token when we send a request to get a protected ressource.
    thank you.

    1. Hi, you can find the way to assign roles to user in the post for backend in this tutorial (signup process)

  28. Hey! I really got to understand all the explanation and followed step by step. But I have a problem everytime I try to Log In, maybe i missed something but i don’t really get the error. I get everytime “Signup failed!
    Error: Role is not found.”

    Thanks for the code! It’s very friendly for the ones that are starting with spring+angular.

  29. Remarks To: Angular 8 JWT Authentication with HttpInterceptor and Router
    It was nice to read your post. It is very organized and detailed. I did not actually implemented and run your code, (because lack of  time these days…). But I liked very much your attitude to intercept all requests (e.g. clone token to all requests) as long as there is “live” token in the memory. leaving the handle of the role-based authorizations in the server side, and save all the headache of dealing with the “whitelist / blacklist” of routs. But of course this have to be managed properly in the server code

  30. Thanks for this excellent material, it was usefull for me and it is really clearly and easy to understand with great explanation. Great job!

Comments are closed to reduce spam. If you have any question, please send me an email.