0

I am trying to authenticate users using JWT. I am assigning a token on login.

if (client) {
      // Check if Client does exist, then compare password provided by Client
      if (!req.body.password) {
        res.json({ success: false, message: "No password provided" }); // Password was not provided
      } else {
        var validPassword = client.password === req.body.password; // Check if password matches password provided by Client
        if (!validPassword) {
          res.json({ success: false, message: {password: {message: "Incorrect Password"}} }); // Password does not match password in database
        } else {
          if (!client.active) {
            res.json({ success: false, message: {active: {message: "Account is not activated"}} }); // Account is not activated
          } else {
            var token = jwt.sign(
              { username: client.username, email: client.email },
              secret,
              { expiresIn: "24h" }
            ); // Logged in: Give Client token
            res.json({
              success: true,
              message: "Client authenticated!",
              token: token
            }); // Return token in JSON object to controller
          }
        }
      }
    }

After login, I am checking the token in requests made my the user.

router.use(function(req, res, next) {   
var token = req.body.token || req.body.query || req.headers['x-access-token']; // Check for token in body, URL, or headers
// Check if token is valid and not expired  
if (token) {
// Function to verify token
    jwt.verify(token, secret, (err, decoded) => {
        if (err) {
            res.json({ success: false, message: 'Token invalid' }); // Token has expired or is invalid
        } else {
            req.decoded = decoded; // Assign to req. variable to be able to use it in next() route ('/me' route)
            next(); // Required to leave middleware
        }
    });
} else {
    res.json({ success: false, message: 'No token provided' }); // Return error if no token was provided in the request
}   

});

I am putting all the protected routes after the check token. Users can access the profile page /me

router.post('/me', function(req, res) {
    res.send(req.decoded); // Return the token acquired from middleware
});

How can I check the token in req.body in Angular 11? I have tried to setToken using localStorage but it seems I am not doing it correctly.

localStorage.setItem('userToken', response.token);

It seems to be working fine in Postman when accessing the /me route by passing the token in body. It shows whether the token found or not. If found then it shows the result

{ "email": "example@gmail.com", "iat": 1634704834, "exp": 1634791234 }

Arun Saini
  • 11
  • 2

1 Answers1

0

Everything seems fine. I think, you just need to implement an interceptor on the frontend side. It will pick the auth token from the local storage, and attach it with all the requests.

Sample code

import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from './service/auth.module';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let loggedInUser = this.authService.currentUserValue;
        token = JSON.parse(localStorage.getItem(user.token));
        if (token) {
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${token}`
                }
            });
        }

        return next.handle(request);
    }
}

And yeah, sending authentication token in the body params is not considered a good practice. Safe method is to use headers always for such sensitive information. More details can be found here

Pankaj Tanwar
  • 850
  • 9
  • 11