fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
932 stars 204 forks source link

Missing or bad formatted authorization header when adding basic auth to protect access to swagger doc #742

Closed nickolasdeluca closed 9 months ago

nickolasdeluca commented 1 year ago

Prerequisites

Issue

After adding basic auth to protect access to our swagger docs, every time I open the URL, after typing the user/password and being granted access, the server throws this error. The weird thing is that this only happens when the code is executed in the production server, when I test localy, this issue doesn't happen. I'm pretty sure this has something to do with cors but I have no idea how to fix it. Specially since my cors config is as open as possible at the moment.

This is the error that is thrown, it doesnt affect the usability of the page. I tested all my routes using the token added through the Authorize button and it works just fine, it's just that it throws this error and the page also loads an invalid badge at the bottom.

{
  "level": 30,
  "time": 1689596704115,
  "pid": 98267,
  "hostname": "project",
  "reqId": "req-9",
  "res": { "statusCode": 401 },
  "err": {
    "type": "FastifyError",
    "message": "Missing or bad formatted authorization header",
    "stack": "FastifyError: Missing or bad formatted authorization header\n    at Object.basicAuth (/opt/project/node_modules/@fastify/basic-auth/index.js:26:12)\n    at hookIterator (/opt/project/node_modules/fastify/lib/hooks.js:293:10)\n    at next (/opt/project/node_modules/fastify/lib/hooks.js:185:16)\n    at /opt/project/node_modules/@fastify/cors/index.js:201:12\n    at resolveOriginOption (/opt/project/node_modules/@fastify/cors/index.js:159:129)\n    at addCorsHeadersHandler (/opt/project/node_modules/@fastify/cors/index.js:161:3)\n    at Object.handleCors (/opt/project/node_modules/@fastify/cors/index.js:64:9)\n    at hookIterator (/opt/project/node_modules/fastify/lib/hooks.js:293:10)\n    at next (/opt/project/node_modules/fastify/lib/hooks.js:185:16)\n    at hookRunner (/opt/project/node_modules/fastify/lib/hooks.js:207:3)",
    "code": "FST_BASIC_AUTH_MISSING_OR_BAD_AUTHORIZATION_HEADER",
    "name": "FastifyError",
    "statusCode": 401
  },
  "msg": "Missing or bad formatted authorization header"
}

This is the code for the basic authentication:

await fastify.register(fastifyBasicAuth, {
  validate(username, password, req, reply, done) {
    let result = true;
    result = username === configuration.swaggerUser && result;
    result = password === configuration.swaggerPass && result;
    if (result) {
      done();
    } else {
      done(new Error("Access denied"));
    }
  },
  authenticate: true,
});

This is my fastify-swagger config:

fastify.register(fastifySwagger, {
  openapi: {
    info: {
      title: "Test API",
      description: "Test API",
      version: "2.0.0",
    },
    servers: [{ url: "/", description: "Test Server" }],
    components: {
      securitySchemes: {
        Bearer: {
          type: "http",
          scheme: "bearer",
          bearerFormat: "JWT",
        },
      },
    },
  },
  hideUntagged: true,
});

This is my fastify-swagger-ui config:

fastify.register(fastifySwaggerUi, {
  routePrefix: "/docs",
  uiConfig: {
    docExpansion: "none",
    deepLinking: true,
  },
  uiHooks: {
    onRequest: fastify.basicAuth,
    preHandler: fastify.basicAuth,
  },
  staticCSP: false,
  logo: {
    type: "image/png",
    content: Buffer.from(swaggerLogo, "base64"),
  },
});

This is my fastify-cors config:

import cors from "@fastify/cors";
fastify.register(cors, { origin: "*" });

It only happens ONCE, when the page is loaded and then it doesn't happen again until I reload the page. Any ideia why this is happening?

mcollina commented 1 year ago

This is how basic authentication works. The browser try send a request to your server and the server ask back the authentication credentials.

nickolasdeluca commented 1 year ago

But it works, why does it throw the error and works as if nothing happened? There must be something I can do...

mcollina commented 1 year ago

Because you receive an error response (401) - https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

nickolasdeluca commented 1 year ago

Look, I don't wanna be rude or anything, but what you've said is obvious, I already know that. I wanna know what can I do to fix this? Because, as I've mentioned, this doesn't happen when I'm running the environment localy...

nickolasdeluca commented 1 year ago

In case anyone finds themselves here with the same issue, it can be mitigated disabling swagger UI's online validator, as mentioned in this Stack Overflow post. It's a Swagger UI config:

fastify.register(fastifySwaggerUi, {
  routePrefix: "/docs",
  uiConfig: {
    docExpansion: "none",
    deepLinking: true,
    validatorUrl: null, /* <-- add this line */
  },
  ...
});

It must be something related to cors, but as I have little experience with it, I can't pinpoint the issue.

Uzlopak commented 9 months ago

This should be solved via https://github.com/fastify/fastify-swagger-ui/pull/105

Closing ;).