1

While my end goal is to prevent Swagger UI from losing authentication upon browser reload, I believe I might have found a solution assuming swagger-ui parameters can be changed when using api-platform, and described it at the tail of this post.

A REST API uses Symfony, API-platform and authenticates using JWT and documentation is provided by swagger-ui. On the swagger-ui page, after submitting the apiKey, future requests include it in the header, however, if the browser is refreshed, the authorization token is lost. enter image description here

There has been some discussion on this topic primarily on this github post and some on this stackoverflow post, and the general consensus seems to be that swagger-ui there is no "official" way to persist tokens.

Overall Swagger UI does not store tokens, and probably on purpose. There is no switch to enable this, but looks like there are little things that can be done to remember a token via cookie, local storage, indexdb, etc and when the page is reloaded, populate the token back in.

The swagger configuration documentation, however, appears to have an Authorization parameter which will allow the authorization data to be persisted upon browser refresh.

  • Parameter name: persistAuthorization
  • Docker variable: PERSIST_AUTHORIZATION
  • Description: Boolean=false. If set to true, it persists authorization data and it would not be lost on browser close/refresh

Assuming I correctly interpret the Swagger documentation, how can the persistAuthorization parameter be set to true?

When modifying config/api_platform.yaml to set persistAuthorization, I received errors Unrecognized option "persistAuthorization" under "api_platform.swagger.api_keys.apiKey". Available options are "name", "type". and Unrecognized option "persistAuthorization" under "api_platform.swagger". Available options are "api_keys", "versions".

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    patch_formats:
        json: ['application/merge-patch+json']
    swagger:
        api_keys:
            apiKey:
                name: Authorization
                type: header
                # persistAuthorization: true
        versions: [3]
        # persistAuthorization: true

I then tried adding a config/swagger-conf.yaml file but received error There is no extension able to load the configuration for "persistAuthorization"

---
persistAuthorization: true

How can one prevent Swagger UI from losing authentication upon browser reload? How does one change a swagger-ui paramters when using API-Platform?

EDIT - NEW INFORMATION

Based on Tarun Lalwani's comment, I found a workaround, however, it is still not ideal. API-Platform either creates public/bundles/apiplatform/init-swagger-ui.js or passes settings to it (I currently do not don't which) based on some of the symfony/api-platform configuration settings. I expected these to be under api_platform.swagger, but after reviewing source code as well as api-platform configuration document, I still don't know how to accomplish it (or even whether it is possible). My workaround was to edit this file directly. Since these bundle files are not typically tracked by git, will need to be sure to manually update. Also, I have some concern should api-platform ever modifies the file.

'use strict';

window.onload = function() {
    const ui = SwaggerUIBundle({
        ...
        persistAuthorization: true, <= Line 49
        ...
    });
};

api_platform.yaml is as follows, but the token is not being persisted.

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    patch_formats:
        json: ['application/merge-patch+json']
    show_webby: false
    swagger:
        api_keys:
            apiKey:
                name: Authorization
                type: header
        versions: [3]
        swagger_ui_extra_configuration:
            persistAuthorization: true,

composer.json now shows "api-platform/core": "2.7.x-dev", but composer recipes api-platform/core still indicates that api-platform 2.5 is being used. I've tried using both PHP7.4 and PHP8. composer depends api-platform/core shows 2.7.x-dev, and I now swagger_ui_extra_configuration exists in the source code which is good, but still tokens are not being persisted.

[michael@devserver api_platform_test]$ composer recipes api-platform/core
name             : api-platform/core
version          : 2.5
status           : up to date
installed recipe : https://github.com/symfony/recipes/tree/7df6db4/api-platform/core/2.5
files            :

├──config
│  ├──packages
│  │  └──api_platform.yaml
│  └──routes
│     └──api_platform.yaml
└──src
   └──Entity
      └──.gitignore
[michael@devserver api_platform_test]$ composer show --tree api-platform/core
api-platform/core dev-main Build a fully-featured hypermedia or GraphQL API in minutes!
├──doctrine/inflector ^1.0 || ^2.0
│  └──php ^7.2 || ^8.0
├──fig/link-util ^1.0
│  ├──php >=8.0.0
│  └──psr/link ^1.1.0 | ^2.0.0
│     └──php >=8.0.0
├──php >=7.1
├──psr/cache ^1.0
│  └──php >=5.3.0
├──psr/container ^1.0
│  └──php >=7.2.0
├──symfony/http-foundation ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-mbstring ~1.1
│  │  └──php >=7.1
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/http-kernel ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──psr/log ~1.0
│  │  └──php >=5.3.0
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/error-handler ^4.4|^5.0
│  │  ├──php >=7.2.5
│  │  ├──psr/log ^1.0
│  │  │  └──php >=5.3.0
│  │  ├──symfony/polyfill-php80 ^1.15
│  │  │  └──php >=7.1
│  │  └──symfony/var-dumper ^4.4|^5.0
│  │     ├──php >=7.2.5
│  │     ├──symfony/polyfill-mbstring ~1.0
│  │     │  └──php >=7.1
│  │     └──symfony/polyfill-php80 ^1.15
│  │        └──php >=7.1
│  ├──symfony/event-dispatcher ^5.0
│  │  ├──php >=7.2.5
│  │  ├──symfony/deprecation-contracts ^2.1
│  │  │  └──php >=7.1
│  │  ├──symfony/event-dispatcher-contracts ^2
│  │  │  ├──php >=7.2.5
│  │  │  └──psr/event-dispatcher ^1
│  │  │     └──php >=7.2.0
│  │  └──symfony/polyfill-php80 ^1.15
│  │     └──php >=7.1
│  ├──symfony/http-client-contracts ^1.1|^2
│  │  └──php >=7.2.5
│  ├──symfony/http-foundation ^4.4|^5.0
│  │  ├──php >=7.2.5
│  │  ├──symfony/deprecation-contracts ^2.1
│  │  │  └──php >=7.1
│  │  ├──symfony/polyfill-mbstring ~1.1
│  │  │  └──php >=7.1
│  │  └──symfony/polyfill-php80 ^1.15
│  │     └──php >=7.1
│  ├──symfony/polyfill-ctype ^1.8
│  ├──symfony/polyfill-php73 ^1.9
│  │  └──php >=7.1
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/property-access ^3.4.19 || ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-php80 ^1.15
│  │  └──php >=7.1
│  └──symfony/property-info ^5.2
│     ├──php >=7.2.5
│     ├──symfony/deprecation-contracts ^2.1
│     │  └──php >=7.1
│     ├──symfony/polyfill-php80 ^1.15
│     │  └──php >=7.1
│     └──symfony/string ^5.1
│        ├──php >=7.2.5
│        ├──symfony/polyfill-ctype ~1.8
│        ├──symfony/polyfill-intl-grapheme ~1.0
│        │  └──php >=7.1
│        ├──symfony/polyfill-intl-normalizer ~1.0
│        │  └──php >=7.1
│        ├──symfony/polyfill-mbstring ~1.0
│        │  └──php >=7.1
│        └──symfony/polyfill-php80 ~1.15
│           └──php >=7.1
├──symfony/property-info ^3.4 || ^4.4 || ^5.2.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-php80 ^1.15
│  │  └──php >=7.1
│  └──symfony/string ^5.1
│     ├──php >=7.2.5
│     ├──symfony/polyfill-ctype ~1.8
│     ├──symfony/polyfill-intl-grapheme ~1.0
│     │  └──php >=7.1
│     ├──symfony/polyfill-intl-normalizer ~1.0
│     │  └──php >=7.1
│     ├──symfony/polyfill-mbstring ~1.0
│     │  └──php >=7.1
│     └──symfony/polyfill-php80 ~1.15
│        └──php >=7.1
├──symfony/serializer ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/polyfill-ctype ~1.8
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/web-link ^4.4 || ^5.1
│  ├──php >=7.2.5
│  └──psr/link ^1.0
│     └──php >=8.0.0
└──willdurand/negotiation ^2.0.3 || ^3.0
   └──php >=7.1.0
[michael@devserver api_platform_test]$ php80 /usr/local/bin/composer show --tree api-platform/core
api-platform/core dev-main Build a fully-featured hypermedia or GraphQL API in minutes!
├──doctrine/inflector ^1.0 || ^2.0
│  └──php ^7.2 || ^8.0
├──fig/link-util ^1.0
│  ├──php >=8.0.0
│  └──psr/link ^1.1.0 | ^2.0.0
│     └──php >=8.0.0
├──php >=7.1
├──psr/cache ^1.0
│  └──php >=5.3.0
├──psr/container ^1.0
│  └──php >=7.2.0
├──symfony/http-foundation ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-mbstring ~1.1
│  │  └──php >=7.1
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/http-kernel ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──psr/log ~1.0
│  │  └──php >=5.3.0
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/error-handler ^4.4|^5.0
│  │  ├──php >=7.2.5
│  │  ├──psr/log ^1.0
│  │  │  └──php >=5.3.0
│  │  ├──symfony/polyfill-php80 ^1.15
│  │  │  └──php >=7.1
│  │  └──symfony/var-dumper ^4.4|^5.0
│  │     ├──php >=7.2.5
│  │     ├──symfony/polyfill-mbstring ~1.0
│  │     │  └──php >=7.1
│  │     └──symfony/polyfill-php80 ^1.15
│  │        └──php >=7.1
│  ├──symfony/event-dispatcher ^5.0
│  │  ├──php >=7.2.5
│  │  ├──symfony/deprecation-contracts ^2.1
│  │  │  └──php >=7.1
│  │  ├──symfony/event-dispatcher-contracts ^2
│  │  │  ├──php >=7.2.5
│  │  │  └──psr/event-dispatcher ^1
│  │  │     └──php >=7.2.0
│  │  └──symfony/polyfill-php80 ^1.15
│  │     └──php >=7.1
│  ├──symfony/http-client-contracts ^1.1|^2
│  │  └──php >=7.2.5
│  ├──symfony/http-foundation ^4.4|^5.0
│  │  ├──php >=7.2.5
│  │  ├──symfony/deprecation-contracts ^2.1
│  │  │  └──php >=7.1
│  │  ├──symfony/polyfill-mbstring ~1.1
│  │  │  └──php >=7.1
│  │  └──symfony/polyfill-php80 ^1.15
│  │     └──php >=7.1
│  ├──symfony/polyfill-ctype ^1.8
│  ├──symfony/polyfill-php73 ^1.9
│  │  └──php >=7.1
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/property-access ^3.4.19 || ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-php80 ^1.15
│  │  └──php >=7.1
│  └──symfony/property-info ^5.2
│     ├──php >=7.2.5
│     ├──symfony/deprecation-contracts ^2.1
│     │  └──php >=7.1
│     ├──symfony/polyfill-php80 ^1.15
│     │  └──php >=7.1
│     └──symfony/string ^5.1
│        ├──php >=7.2.5
│        ├──symfony/polyfill-ctype ~1.8
│        ├──symfony/polyfill-intl-grapheme ~1.0
│        │  └──php >=7.1
│        ├──symfony/polyfill-intl-normalizer ~1.0
│        │  └──php >=7.1
│        ├──symfony/polyfill-mbstring ~1.0
│        │  └──php >=7.1
│        └──symfony/polyfill-php80 ~1.15
│           └──php >=7.1
├──symfony/property-info ^3.4 || ^4.4 || ^5.2.1
│  ├──php >=7.2.5
│  ├──symfony/deprecation-contracts ^2.1
│  │  └──php >=7.1
│  ├──symfony/polyfill-php80 ^1.15
│  │  └──php >=7.1
│  └──symfony/string ^5.1
│     ├──php >=7.2.5
│     ├──symfony/polyfill-ctype ~1.8
│     ├──symfony/polyfill-intl-grapheme ~1.0
│     │  └──php >=7.1
│     ├──symfony/polyfill-intl-normalizer ~1.0
│     │  └──php >=7.1
│     ├──symfony/polyfill-mbstring ~1.0
│     │  └──php >=7.1
│     └──symfony/polyfill-php80 ~1.15
│        └──php >=7.1
├──symfony/serializer ^4.4 || ^5.1
│  ├──php >=7.2.5
│  ├──symfony/polyfill-ctype ~1.8
│  └──symfony/polyfill-php80 ^1.15
│     └──php >=7.1
├──symfony/web-link ^4.4 || ^5.1
│  ├──php >=7.2.5
│  └──psr/link ^1.0
│     └──php >=8.0.0
└──willdurand/negotiation ^2.0.3 || ^3.0
   └──php >=7.1.0
[michael@devserver api_platform_test]$ php80 /usr/local/bin/composer recipes api-platform/core
name             : api-platform/core
version          : 2.5
status           : up to date
installed recipe : https://github.com/symfony/recipes/tree/7df6db4/api-platform/core/2.5
files            :

├──config
│  ├──packages
│  │  └──api_platform.yaml
│  └──routes
│     └──api_platform.yaml
└──src
   └──Entity
      └──.gitignore
[michael@devserver api_platform_test]$
user1032531
  • 24,767
  • 68
  • 217
  • 387
  • Possible to look at the setup you have? I am not sure how the document generation is working. But see if this link https://github.com/psfpro/ddd-cms-sample/blob/c477615d82ec7e8b3607f48f8bdce42787f78ec9/public/docs/index.php#L50 helps you – Tarun Lalwani Mar 18 '21 at 15:47
  • @TarunLalwani The setup is managed by API-Platform based on the settings in config/packages/api_platform.yaml which are shown on my initial post. Based on your comment, I found a workaround solution and posted at the end of my initial post. Still, would like a more maintainable solution, however, this will work in the interim. If you have a better idea, please advise. Thanks! – user1032531 Mar 20 '21 at 14:57
  • There looks to be a better way, which is to set the `extraConfiguration` https://github.com/api-platform/core/blob/930c930debe0f14fd7c6a0a46034d9e858f17846/tests/Bridge/Symfony/Bundle/Action/SwaggerUiActionTest.php#L127, just find which place – Tarun Lalwani Mar 20 '21 at 15:09
  • Agree that would be a better way. When installing using git, I see that `swagger_ui_extra_configuration` is now a property in the api_platform.yaml under swagger, but is not available when installed by composer. Appreciate the help! – user1032531 Mar 20 '21 at 17:02
  • Which version you are using in composer `2.6.3`? – Tarun Lalwani Mar 20 '21 at 17:28
  • composer.json includes `"api-platform/core": "^2.6",`, but `composer recipes api-platform/core` shows 2.5. – user1032531 Mar 20 '21 at 17:39
  • It is coming in `2.7.0` it seems https://github.com/api-platform/core/blob/7ba0628089d2239afeebb562d0589411e569854c/CHANGELOG.md – Tarun Lalwani Mar 20 '21 at 17:47

2 Answers2

2

You can for now use the dev version

composer require "api-platform/core:2.7.x-dev"

And then use the swagger_ui_extra_configuration which was added as a part of below pull request

https://github.com/api-platform/core/pull/3731

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • Thanks Tarun, Made the changes but the token is not being persisted. First thought it was because composer wasn't updating to 2.7, but not sure now. I posted output to the bottom of the original post and would appreciate any suggestions. Thank you – user1032531 Mar 20 '21 at 18:31
  • For unknown reasons, didn't work under swagger in api_platform.yaml but did work under openapi. Also, potentially didn't work wiht php7.4 but only php8. All good! – user1032531 Mar 20 '21 at 19:04
0

you can update your config like this to persist the jwt token during reload:

#api/config/packages/api_platform.yaml

api_platform:
    swagger:
        api_keys:
            JWT:
                name: Authorization
                type: header
        swagger_ui_extra_configuration:
            persistAuthorization: true
Sebastian Viereck
  • 5,455
  • 53
  • 53