title: NodeJS and AngularJS - Secure REST API with Client Certificate Authentication
body: <p>I am currently working on making my REST Api Server (NodeJS + Express + Mongoose) secure, so nobody, except my client application (AngularJS 1.6) and my admin application (based on AngularJS 1.6), can access the routes and fetch or put data into my database. Everything is running on https with a valid SSL certificate.</p>
  
  <p>I mainly thought about two approaches:</p>
  
  <ol>
  <li>Shared secret keys where specific routes needs an "access key"</li>
  <li>Client certificate authentication </li>
  </ol>
  
  <p>I went with no. 2, because in my thoughts this is the most secure (please correct if I am wrong :))</p>
  
  <p>So I set up my API Server to run on https and request a valid client certificate:</p>
  
  <pre><code>var options = {
      ca: fs.readFileSync(__dirname + "/cert/server.ca"),
      key: fs.readFileSync(__dirname + "/cert/server.key"),
      cert: fs.readFileSync(__dirname + "/cert/server.crt"),
      requestCert: true,
      rejectUnauthorized: false
  };
  
  https.createServer(options, app)
      .listen(PORT, () =&gt; {
          console.log(`up and running @: ${os.hostname()} on port: ${PORT}`);
          console.log(`enviroment: ${process.env.NODE_ENV}`);
      });
  </code></pre>
  
  <p>I handle the rejection of unathorized users directly in the app via:</p>
  
  <pre><code>if (!req.client.authorized) {
      var cert = req.socket.getPeerCertificate();
      console.log("unauthorized: ", cert);
      return res.status(401).send('Not authorized!');
  }
  </code></pre>
  
  <p>And here the problems begin :). On every request my client application does I receive an error:</p>
  
  <blockquote>
    <p>401 - not authorized</p>
  </blockquote>
  
  <p>I thought that the client application is sending the SSL certificate with every request (or if requested by nodejs) via "requestCert" and everything is working just fine. But it seems to be a bit more complicated.</p>
  
  <p>In my <code>server.ca</code> file I currently have the certificate chain which I received from the CA. </p>
  
  <p>In <code>console.log</code> the transmitted certificate in the request, but its always empty. </p>
  
  <p>What am I doing wrong? Do I have to configure Angular to send it along with every request? Any suggestions?</p>