Swagger-ui: Integrating an own component for ApiKeyAuth via Plugin API doesn't work

Created on 4 May 2018  路  6Comments  路  Source: swagger-api/swagger-ui

| Q | A
| ------------------------------- | -------
| Bug or feature request? | Bug (probably)
| Which Swagger/OpenAPI version? | 2.0
| Which Swagger-UI version? | 3.13.4
| How did you install Swagger-UI? | via npm/webpack
| Which browser & version? | Safari 11.1
| Which operating system? | MacOS 10.13.4

In our project we use the plugin api to override several components, such as InfoUrl and InfoBasePath which works like expected. If we try the same for the component ApiKeyAuth it doesn't have any impact to our UI, even if we cancel it out completely:

export const ApiKeyAuthPlugin = () => {
    return {
        components: {
            ApiKeyAuth: () => null
        }
    }
}

Demonstration API definition


"security": [
    {
        "api_key": []
    }
],
"securityDefinitions": {
    "api_key": {
        "in": "header",
        "name": "x-api-key",
        "type": "apiKey",
    }
},

Expected Behavior



With the above described plugin, the component should be cleared out which should result in an empty modal in our UI.

Current Behavior



Nothing happens. The UI looks like without a plugin at all.

Context



We need to set a default apiKey for our tryout requests from swagger-ui. So the users can decide whether they want to use the default one or their own. Therefore, we want to display the apiKey as a default in the authorization modal. Additionally this apiKey should even be set as default before the user clicks authorize. As this is not possible with the current swagger-ui, we want to create our own plugin to overwrite the apiKeyAuth component.

lock-bot

Most helpful comment

Hi @ChristophWalter!

If we try the same for the component ApiKeyAuth it doesn't have any impact to our UI, even if we cancel it out completely:

Try using apiKeyAuth instead of ApiKeyAuth 馃槃 component names are case-sensitive, and not 100% consistent across the project...

To quote myself in #4431:

For context: #3393 is open, to make component names case-insensitive. There was a PR for the issue (#3419), which stored all components internally as lower-case, and then downcased all component lookups - but the contributor withdrew the code 馃槩

For future reference, you can use the getComponents method to see an object with every component's name as a key, though in a perfect world you wouldn't have to care about the case.


Don't know how to access values within the swaggerfile during initialization, yet.

You can do this from within an onComplete, like so:

const ui = SwaggerUI({
  url: "http://petstore.swagger.io/v2/swagger.json",
  onComplete: () => {
    const spec = ui.specSelectors.specJson() // this is an Immutable.js Map
    const tokenValue = spec.getIn(["securityDefinitions", "MyAuth", "x-default"])

    ui.preauthorizeApiKey("MyAuth", tokenValue)
  }
})

All 6 comments

The default API key can be set using preauthorizeApiKey. This is supported in Swagger UI 3.13.0+. Is this what you are looking for?

// index.html

const ui = SwaggerUIBundle({
  url: "https://my.api.com/swagger.yaml",
  ...
  onComplete: function() {
    // "api-key" is the key name of the security scheme in securityDefinitions
    ui.preauthorizeApiKey("api-key", "abcde12345");
  }
})

Thanks for your fast response. For this specific case using preauthorizeApiKey might help us to find a solution. But in general it should be possible to overwrite every component with help of the plugin api, or am I wrong?

Anyway, there are some more challenges to solve. Our current plan is to ship the default apiKey within the swaggerfile using a custom field, e.g.:

'security': [
    {
        'ApiKeyAuth': [],
        'x-default-apikey': 'abc123'
    }
],

How can we access this during SwaggerUI initialization? Or how can we access ui.preauthorizeApiKey using a plugin? And we need the same default token for oauth2, as not all of our apis use apikeys...

Update:
Found a solution to set a default oauth2 id and secret here: https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/oauth2.md
Don't know how to access values within the swaggerfile during initialization, yet.

Hi @ChristophWalter!

If we try the same for the component ApiKeyAuth it doesn't have any impact to our UI, even if we cancel it out completely:

Try using apiKeyAuth instead of ApiKeyAuth 馃槃 component names are case-sensitive, and not 100% consistent across the project...

To quote myself in #4431:

For context: #3393 is open, to make component names case-insensitive. There was a PR for the issue (#3419), which stored all components internally as lower-case, and then downcased all component lookups - but the contributor withdrew the code 馃槩

For future reference, you can use the getComponents method to see an object with every component's name as a key, though in a perfect world you wouldn't have to care about the case.


Don't know how to access values within the swaggerfile during initialization, yet.

You can do this from within an onComplete, like so:

const ui = SwaggerUI({
  url: "http://petstore.swagger.io/v2/swagger.json",
  onComplete: () => {
    const spec = ui.specSelectors.specJson() // this is an Immutable.js Map
    const tokenValue = spec.getIn(["securityDefinitions", "MyAuth", "x-default"])

    ui.preauthorizeApiKey("MyAuth", tokenValue)
  }
})

Hi @shockey!

Thanks a lot for your response. 馃憤

Try using apiKeyAuth instead of ApiKeyAuth 馃槃 component names are case-sensitive, and not 100% consistent across the project...

Using apiKeyAuth works, great!


I spotted ui.specSelectors.specJson() and started going deeper in deeper:

ui.specSelectors.specJson()._list._tail.array.find(...)

Never worked with Immutable.js before, so thanks for this hint. Looks much better!

@ChristophWalter no problem! Immutable has a very powerful API, for this particular thing you can use ui.specSelectors.specJson().getIn(["a", "deep", "path"]) to grab a value deeply within your data. Or you could always use ui.specSelectors.specJson().toJS() if you want a plain JS object 馃槃

Locking due to inactivity.

This is done to avoid resurrecting old issues and bumping long threads with new, possibly unrelated content.

If you think you're experiencing something similar to what you've found here: please open a new issue, follow the template, and reference this issue in your report.

Thanks!

Was this page helpful?
0 / 5 - 0 ratings