title: How to access the API Key inside node express server code that is auto-generated by the OpenAPI generator
body: <p><strong>Quickest Question Summary:</strong>
  I've struggled with this. I've posted my most succinct statement of my problem <a href="https://github.com/cdimascio/express-openapi-validator/issues/633" rel="nofollow noreferrer">here</a>. That issue, references this one on stack, and another on the openapi generator.</p>
  <p><strong>Initial Question:</strong></p>
  <p>I'll open with the question, and then provide context.</p>
  <p><strong>Question:</strong>
  How can I modify the <a href="https://github.com/OpenAPITools/openapi-generator" rel="nofollow noreferrer">autogenerated OpenAPI</a> <a href="https://expressjs.com/" rel="nofollow noreferrer">node express</a> code (illustrated, in part, below) to get access to the API key stored in the header (or parameter list) of requests to protected routes?</p>
  <p>I dont want to modify the route middleware at the route endpoint. I think the right thing to do is to use an additional intermediate middleware that intercepts the API key, checks the database for the user roles, and then passes to the next middleware in the chain, only if the user has an appropriate role.</p>
  <p>So, how do I code this intermediate <em>API Key-to-Role Checker</em> middleware, use it within the middleware stack registered on protected routes, and how does it access the API key in the request header?</p>
  <p>I would have thought that the auto-generated node express code would make this plainly visible and accessible. However an easy to use application tier hook that accesses the API key ( to allow for <a href="https://en.wikipedia.org/wiki/Role-based_access_control" rel="nofollow noreferrer">RBAC</a> checks on that key) is seemingly missing. Also I've not found adequate documentation online that talks to this piece of the OpenAPI application pipeline.</p>
  <p>I've even purchased <a href="https://wing328.gumroad.com/l/openapi_generator_ebook" rel="nofollow noreferrer">this book</a>, hoping to find the answer to such questions. The book did an inadequate job of talking to the application tier concerns that surround security, api key handling, and such.</p>
  <p><strong>Context:</strong>
  I am using the <a href="https://github.com/OpenAPITools/openapi-generator" rel="nofollow noreferrer">OpenAPI generator</a> to create both my node express service, and my client libraries.</p>
  <p>I have a working service, and a working <a href="https://material-ui.com/" rel="nofollow noreferrer">MaterialUI</a>/<a href="https://reactjs.org/" rel="nofollow noreferrer">React</a> client application that can access GET, POST, PUT, and DEL routes on that service. However I am adding the ability to authenticate and authorize users. I am using the API key mechanism for now. Eventually I will also use oauth2. However I'll focus this question on the API key.</p>
  <p>Currently the service accepts any API key (even a hard-coded key), for those routes that require the presence of a key. The means to authenticate/authorize is left open to the designer.</p>
  <p>The service code needs access to the key in order to allow me to implement RBAC.</p>
  <p>I've decided to use JWT's (Java Web Tokens), as part of the user registration and login process. I've actually followed <a href="https://www.youtube.com/watch?v=Ne0tLHm1juE&amp;list=PLYQSCk-qyTW2ewJ05f_GKHtTIzjynDgjK&amp;index=11&amp;t=1537s" rel="nofollow noreferrer">this tutorial</a> relative to adding JWT registration and login to my application. I've also added <a href="http://www.passportjs.org/" rel="nofollow noreferrer">passport</a> to my application (but I'm not really using this yet), since I thought I'd use that as part of the login process (it provides seamless support for protocols other than JWT).</p>
  <p>All that (the JWT registrtion/login) seems to work as well. My web application is a react/material UI application. I have modified it to allow for user registration and login. That works. The server returns a JWT to the web app. My thought was that I would use the token in the JWT as the API key (for subsequent requests to protected service routes).</p>
  <p>What I dont know how to do is to access that key on the service itself. The openAPI library that the auto-generated service is using simply hides that piece of the application middleware.</p>
  <p>This is the autogenerated service class.  I've added Mongoose, since I store my user information in a backend mongo database.</p>
  <p>Notice that the class uses <a href="https://github.com/cdimascio/express-openapi-validator" rel="nofollow noreferrer">express-openapi-validator</a></p>
  <pre><code>const http = require('http');
  const fs = require('fs');
  const path = require('path');
  const swaggerUI = require('swagger-ui-express');
  const jsYaml = require('js-yaml');
  const express = require('express');
  const cors = require('cors');
  const cookieParser = require('cookie-parser');
  const bodyParser = require('body-parser');
  const { OpenApiValidator } = require('express-openapi-validator');
  const passport = require('passport');
  const logger = require('./logger');
  const config = require('./config').getConfig();
  const { MongoDatabase } = require('./database');
  const { OpenApiValidator } = require('express-openapi-validator');
  
  
  class ExpressServer {
    constructor(port, openApiYaml, keys) {
      this.port = port;
      this.app = express();
      this.openApiPath = openApiYaml;
  
      try {
        this.schema = jsYaml.safeLoad(fs.readFileSync(openApiYaml));
      } catch (e) {
        logger.error('failed to start Express Server', e.message);
      }
      this.setupMiddleware();
    }
  
    setupMiddleware() {
      // this.setupAllowedMedia();
     
      this.app.use(cors());
      this.app.use(bodyParser.json({ limit: '14MB' }));
      this.app.use(express.json());
      this.app.use(express.urlencoded({ extended: false }));
      this.app.use(cookieParser());
  
      // Simple test to see that the server is up and responding
      this.app.get('/hello', (req, res) =&gt; res.send(`Hello World. path: ${this.openApiPath}`));
      // Send the openapi document *AS GENERATED BY THE GENERATOR*
      this.app.get('/openapi', (req, res) =&gt; res.sendFile((path.join(__dirname, 'api', 'openapi.yaml'))));
      // View the openapi document in a visual interface. Should be able to test from this page
      this.app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(this.schema));
      this.app.get('/login-redirect', (req, res) =&gt; {
        res.status(200);
        res.json(req.query);
      });
      this.app.get('/oauth2-redirect.html', (req, res) =&gt; {
        res.status(200);
        res.json(req.query);
      });
    }
  
    launch() {
      new OpenApiValidator({
        apiSpec: this.openApiPath,
        operationHandlers: path.join(__dirname),
        fileUploader: { dest: config.FILE_UPLOAD_PATH },
      }).install(this.app)
        .catch((e) =&gt; console.log(e))
        .then(() =&gt; {
          // eslint-disable-next-line no-unused-vars
          this.app.use((err, req, res, next) =&gt; {
            // format errors
            res.status(err.status || 500).json({
              message: err.message || err,
              errors: err.errors || '',
            });
          });
  
          http.createServer(this.app).listen(this.port);
          console.log(`Listening on port ${this.port}`);
        });
  
      MongoDatabase.connect(config.db.mongo_url);
    }
  
    async close() {
      if (this.server !== undefined) {
        await this.server.close();
        console.log(`Server on port ${this.port} shut down`);
      }
    }
  }
  </code></pre>
  <p>Here is a sample service route (to delete an order):</p>
  <pre><code>const deleteOrder = ({ orderId }) =&gt; new Promise(
    async (resolve, reject) =&gt; {
      try {
        resolve(Service.successResponse({
          orderId,
        }));
      } catch (e) {
        reject(Service.rejectResponse(
          e.message || 'Invalid input',
          e.status || 405,
        ));
      }
    },
  );
  </code></pre>
  <p>I'd like to be able to use the API key to search into my mongo database, in order to see if the user has the appropriate role (I dont want just any authenticated user to be able to delete an order). Notice that the deleteOrder method above, does not have access to this API key. Furthermore its not the right place to perform that check. As mentioned in the question above, the right place to do that check is in an intermediate application middleware that intercepts the API key, and checks it against the user information in the database, to ensure that the user has an appropriate role.</p>
  <p>The following code snippets, are the currently working  functions called on my registration and login routes. Notice that these handle the JWT creation process on password validation.</p>
  <pre><code>const createUser = ({ user }) =&gt; new Promise(
    async (resolve, reject) =&gt; {
      console.log('createUser: ', user);
      const saltHash = jwtUtils.genPassword(user.password);
  
      const newUser = new User({
        username: user.username,
        firstName: user.firstName,
        lastName: user.lastName,
        email: user.email,
        phone: user.phone,
        userStatus: user.userStatus,
        hash: saltHash.hash,
        salt: saltHash.salt,
      });
  
      try {
        newUser.save()
          .then((usr) =&gt; {
            console.log('createUser: Added ', usr);
            // eslint-disable-next-line no-underscore-dangle
            const jwt = jwtUtils.issueJWT(usr);
            const rtn = {
              _id: usr._id.toString(),
              firstName: usr.firstName,
              lastName: usr.lastName,
              token: jwt.token,
              expiresIn: jwt.expires,
            };
            resolve(Service.successResponse(rtn));
          });
      } catch (err) {
        console.log('createUser: Error ', err);
        reject(Service.rejectResponse(
          err.message || 'Invalid input',
          err.status || 405,
        ));
      }
    },
  );
  
  const loginUser = ({ username, password }) =&gt; new Promise(
    async (resolve, reject) =&gt; {
      console.log('loginUser: ', username);
      try {
        User.findOne({ email: username })
          .then((usr) =&gt; {
            if (!usr) {
              reject(Service.rejectResponse(
                'Invalid user',
                401,
              ));
            }
  
            const isValid = jwtUtils.validPassword(password, usr.hash, usr.salt);
            if (isValid) {
              const jwt = jwtUtils.issueJWT(usr);
  
              const rtn = {
                _id: usr._id.toString(),
                firstName: usr.firstName,
                lastName: usr.lastName,
                token: jwt.token,
                expiresIn: jwt.expires,
              };
              resolve(Service.successResponse(rtn));
            } else {
              reject(Service.rejectResponse(
                'Invalid password',
                401,
              ));
            }
          })
          .catch((err) =&gt; {
            reject(Service.rejectResponse(
              err.message || 'Invalid input',
              err.status || 405,
            ));
          });
      } catch (e) {
        reject(Service.rejectResponse(
          e.message || 'Invalid input',
          e.status || 405,
        ));
      }
    },
  );
  </code></pre>
  <p>Lastly, here is a sample snippet of code on the client side, that shows how the API key gets into the service request. Notice, that it is currently hard-coding that key, and is not yet using the JWT token as the key. Yet, the service is perfectly happy with this hard-coded key. <em><strong>I'm trying to fix that!</strong></em> <em>That is the essence of my question!</em></p>
  <pre><code>let defaultClient = ApiClient.instance
  defaultClient.basePath = window._env_.API_URL
  
  let api_key = defaultClient.authentications['api_key'];
  api_key.apiKey = 'YOUR API KEY';
  
  let apiInstance = new VideoApi(defaultClient);
  
  export function requestGetVideos(test, id) {
      let p = new Promise((resolve, reject) =&gt; {
          apiInstance.getVideoInventory((error, data, response) =&gt; {
            if (error) {
              console.error(error);
              reject(error);
            } else {
              resolve({&quot;data&quot;: data, &quot;response&quot;: response});
            }
          });
      })
      return p;
  }
  </code></pre>
  <hr />
  <p>Follow On Detail.</p>
  <p>The autogenerated code is using the 3.9 version of the validator.
  <a href="https://i.stack.imgur.com/WhsSg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/WhsSg.png" alt="The dependencies in my auto-generated service" /></a></p>
  <p>Looking at the <a href="https://github.com/cdimascio/express-openapi-validator" rel="nofollow noreferrer">documentation on the validator</a>, I was trying to find how to add the token validator to the routes that are setup by the openapi-validator.</p>
  <p><a href="https://i.stack.imgur.com/5wYk3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5wYk3.png" alt="The documentation says that the &quot;install&quot; method goes away with the 4.x version of the validator" /></a></p>
  <p>So its not clear how to add an app middleware on the routes that are setup by the validator when it loads the <em>apiSpec</em> specified in the call to its constructor.
  <a href="https://i.stack.imgur.com/545Jc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/545Jc.png" alt="The instantiation of the validator with the apiSpec pointing to the yml file that describes my application routes" /></a></p>