Skip to content

Support in: query for securitySchemes of type apiKey #1150

@justinrlle

Description

@justinrlle

Describe the bug

For our users to authenticate with our APIs, they need to specify a query parameter to be sent with all requests, one of the reasons being that we can identify more easily in logs, while not leaking the actual API key.

To express this, we use the following configuration in securitySchemes:

components:
  securitySchemes:
    App_ID:
      type: apiKey
      in: query
      name: appId
      description: provided in the URL as a query parameter `?appId=<id>`, meant  to publicly identify your account, it is not a sensitive information.

We would love to use your plugin to document our API (which, honestly, looks like one of the most straightforward, powerful and beautiful solution out there), but it currently doesn't support securitySchemes of the type apiKey where the parameter in is something else than header.

Here is a link to the documentation of the API keys under OpenAPI, but I think I've seen in your code at some places the union 'header' | 'query' | 'cookie'.

Expected behavior

When specifying the value for the App_ID security scheme, it should be included in both the code samples and in the request.

Current behavior

The value is not included.

Possible solution

  1. Include the value in the query of the request. If I've understood well, here is the part that build the request:

    if (a.type === "apiKey" && a.in === "header") {
    const { apiKey } = auth.data[a.key];
    if (apiKey === undefined) {
    otherHeaders.push({
    key: a.name,
    value: `<${a.name ?? a.type}>`,
    });
    continue;
    }
    otherHeaders.push({
    key: a.name,
    value: apiKey,
    });
    continue;
    }
    }

  2. Render the documentation on the scheme with the right description, e.g. it should say Query parameter name instead of Header parameter name:

    switch (type) {
    case "apiKey":
    return create("div", {
    children: [
    create("table", {
    children: create("tbody", {
    children: [
    createSecuritySchemeTypeRow(),
    create("tr", {
    children: [
    create("th", { children: "Header parameter name:" }),
    create("td", { children: name }),
    ],
    }),
    ],
    }),
    }),
    ],
    });

  3. Include the value in the code samples. I think it should be fine to display the value without hiding it, because, to my understanding, this kind of security scheme is not for sensitive data and the query of an URL is considered public in security terms. But at least to have the value visible to be replaced would be great.

  4. If the value is to be displayed right-away in the code samples, don't hide the value of the FormInput, that would be redundant.

    <FormTextInput
    placeholder={`${a.key}`}
    password
    value={data[a.key].apiKey ?? ""}
    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    dispatch(

Steps to reproduce

  1. Define a security scheme with type apiKey, configured to be included in the query and not in the headers. (cf minimal example in section below)
  2. Check the documentation for the authentication scheme, where you can read Header parameter name even though it's supposed to be in the header
  3. Use the "Send a request" feature with a value specified for the apiKey
  4. Neither the code samples nor the actual request include the apiKey value specified just above.

Screenshots and files

test.yaml file which define a simple security scheme, which should be echoed by the httpbingo.org

---
openapi: 3.0.3
info:
  title: Test API key in Header
  version: 1.0.0
servers:
  - url: https://httpbingo.org
tags:
  - name: Test
paths:
  /get:
    get:
      operationId: getTest
      tags:
        - Test
      summary: Test the securityScheme
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  args:
                    type: object
                    properties:
                      appId: # should be present, because it will be inserted as a query param
                        type: array
                        items:
                          type: string
                    additionalProperties:
                      type: array
                      items:
                        type: string
                additionalProperties: true
components:
  securitySchemes:
    App_ID:
      type: apiKey
      in: query
      name: appId
      description: Provided in the URL as a query parameter `?appId=<id>`, meant  to publicly identify your account, it is not a sensitive information.
security:
  - App_ID: []

Plugin config:

test: {
    specPath: './test.yaml',
    outputDir: 'docs/test',
    label: 'Test',
    sidebarOptions: {
        groupPathsBy: 'tag',
        categoryLinkSource: 'tag',
    },
    showSchemas: true,
    hideSendButton: false,
} satisfies OpenApiPlugin.Options,

Description of the security scheme with docusaurus-openapi-docs:
Image

Description of the security scheme with swagger-ui (ran locally with docker):
Image

Sending the request with docusaurus-openapi-docs:
Image
The App_ID is set in the request, but it's not present in the code sample, and neither in the response

Sending the request with swagger-ui:
Image
We can see in the curl sample the appId field, we can also see it in the Request URL, and in the response.

Context

This issue is preventing us to migrate to docusaurus. Honestly, your plugin looks like the best way to integrate an OpenAPI spec in a website, and has a lot of features, but for us to start the migration, we would need to have this fixed.

The alternative for me is to disable the “Send API Request” feature, but that means that the code sample are still not correct, because they won't include the necessary query param.

Your Environment

  • Version used: 4.4.0, just started experimenting earlier today.

PS: Sorry for the long bug report, I've spent a bit of time trying to understand why my credential wasn't included in the request, and in the end I had nearly a full bug report ready. So here it is!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions