1

I am building an app with a back-end in NodeJS 12 Express 4 and a front-end client SPA in Angular 8. I am building local authentication with the PassportJS local authentication strategy.

Auth workflow:

A GET request is sent to the /login endpoint and the login page is loaded.

Note: The login page is NOT in the SPA, it is a simple pug page with a form that sends a to POST to the /login endpoint.

GET /login

router.get('/', (req, res, next) => {
  return res.render('login');
});

The user enters their credentials, submits the form and sends a POST request to /login. The Passport local strategy checks the credentials and then in the callback, creates a JWT to be sent back to the client.

This is where I am getting stuck. If I had the login page in the SPA, I could just send an AJAX request and get the response back to the client as JSON e.g. return res.json(jwtToken) and the SPA could parse the token and store it in session storage directly.

However, since the login page is on the server directly, how can I send the token back to the client?

At the moment, I am trying to place the token in the auth header and 'redirect' to the client URL. This is working (I can see the auth token in the browser console) but how does can the SPA read the token on the Angular side? Angular would need to access the HTTP Headers, get the token and save it in the session storage.

POST /login

router.post('/', (req, res, next) => {

  // Passport authentication strategy
  passport.authenticate('local', function (err, user, info) {
    // Callback after authentication strategy is complete

    // Check error
    if (err) {
      console.error(err);
      return res.status(404).json(err);
    }

    // Check if user was returned
    if (user) {

      // Generate JWT token
      let jwt;
      jwtToken = generateJwt();


      // Set authorization header
      res.set({
        'Content-Type': 'application/json',
        'Authorization': `Bearer: ${jwtToken}`,
      });

      // Redirect to the client
      return res.redirect('http://localhost:4200/login');

      //return res.json(jwtToken);

    }
  })(req, res);
});

Question:

In the Angular component, is it possible to parse the Authorization header to get the token that was sent by the server? I tried using the activatedRoute module but wasn't able to get access to the header data from the initial page load. I also tried adding the token as a URL parameter in the GET request but that makes the URL extremely long and exposes the token in plain text. Are there any reasonable ways send the token from the server to the client safely?

UPDATE:

I am going to try sending the token in a cookie using express cookieParser similar to this answer in another post. That way the SPA can access the token saved in the cookie, parse it, and then save it in session storage. However, I am hesitant to do this and am not sure if this is going to be the most sustainable technique, since this requires an additional module to parse the cookie in the SPA.

  let options = {
    maxAge: 1000 * 60 * 15,
    httpOnly: false,
    signed: true
  }

  // Set cookie
  res.cookie('jwt-token', jwt, options)

  // Redirect to the client
  return res.redirect(302, 'http://localhost:4200/login');
pengz
  • 2,279
  • 3
  • 48
  • 91

0 Answers0