Swagger UI 将身份验证令牌传递给 API 调用 header

Swagger UI passing authentication token to API call in header

我是 Swagger 新手。

我正在使用 Swagger UI 生成 swagger 文档。我有两个 API 电话。第一个调用是根据用户名和密码生成令牌。第二次调用需要第一次调用生成的令牌。

我如何使用 Swagger 为第二次调用设置该令牌 UI?

我认为您必须自定义 swagger index page 才能实现。

您可以隐藏输入 'input_apiKey' 并为用户名和密码添加两个输入。然后你进行 ajax 调用以使用你的令牌更新隐藏的输入。

@ApiImplicitParams and @ApiImplicitParam 应该可以解决问题:

@GET
@Produces("application/json")
@ApiImplicitParams({
    @ApiImplicitParam(name = "Authorization", value = "Authorization token", 
                      required = true, dataType = "string", paramType = "header") })
public String getUser(@PathParam("username") String userName) {
    ...
}

来自documentation

You may wish you describe operation parameters manually. This can be for various reasons, for example:

  • Using Servlets which don't use JAX-RS annotations.
  • Wanting to hide a parameter as it is defined and override it with a completely different definition.
  • Describe a parameter that is used by a filter or another resource prior to reaching the JAX-RS implementation.

Swagger UI 将更新,以便您可以从那里发送您的令牌。 HTML 无需更改。


注: 不久前,在用 Swagger 记录 REST API 时,我意识到只需添加 @ApiImplicitParam is not enough (even if you have only one parameter). Anyway, you must add @ApiImplicitParams

这是一个老问题,但这是我最近用我的 JWT 令牌的 2.7.0 版解决它的方法

在你的 swagger 配置中,添加 below SecurityConfiguration bean。重要的是将第五个参数留空或为空。

@Bean
    public SecurityConfiguration securityInfo() {
        return new SecurityConfiguration(null, null, null, null, "", ApiKeyVehicle.HEADER,"Authorization","");
    }

securitySchemes(Lists.newArrayList(apiKey())) 添加到您的主要 Docket bean。

@Bean
    public Docket docket()
    {
        return new Docket(DocumentationType.SWAGGER_2).select()
            .....build().apiInfo(...).securitySchemes(Lists.newArrayList(apiKey()));
    }


    private ApiKey apiKey() {
        return new ApiKey("Authorization", "Authorization", "header");
    } 

然后在 UI 中,您需要单击 Authorize 按钮并输入 "Bearer access_token"(用于授权文本框),其中 access_token 是 jWT 令牌服务器提供的令牌。

此权限保存后,对所有端点生效。为每个端点添加一个单独的文本字段看起来非常麻烦。

我对 2.9.2 Swagger 版本的配置在 Swagger UI 上添加授权并发送 Bearer 令牌

    @Configuration
    public class SwaggerConfiguration{

        //...

          @Bean
          public Docket api(ServletContext servletContext) {
            return new Docket(DocumentationType.SWAGGER_2)...
                .securitySchemes(Arrays.asList(apiKey()))
                .securityContexts(Collections.singletonList(securityContext()));
          }

          private SecurityContext securityContext() {
            return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex("/.*")).build();
          }

          private List<SecurityReference> defaultAuth() {
            final AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
            final AuthorizationScope[] authorizationScopes = new AuthorizationScope[]{authorizationScope};
            return Collections.singletonList(new SecurityReference("Bearer", authorizationScopes));
          }

          private ApiKey apiKey() {
            return new ApiKey("Bearer", "Authorization", "header");
          }
    } 

有一个黑客可以通过使用 responseInterceptor 和 requestInterceptor 来工作

首先使用 responseInterceptor 捕获第一个 API 调用的响应并保存令牌(在本地存储的示例中),然后使用 requestInterceptor 添加 Authorization header 使用保存的令牌。

            const ui = SwaggerUIBundle({
               ...
                responseInterceptor:
                    function (response) {
                        if (response.obj.access_token) {
                            console.log(response.obj.access_token)
                            const token = response.obj.access_token;
                            localStorage.setItem("token", token)
                        }

                        return response;
                    },
                requestInterceptor:
                    function (request) {
                        console.log('[Swagger] intercept try-it-out request');
                        request.headers.Authorization = "Bearer " + localStorage.getItem("token");
                        return request;
                }
           }

另一种选择是添加globalOperationParameters。它将在每个端点中添加一个授权字段。

定义授权header参数:

Parameter authHeader = new ParameterBuilder()
  .parameterType("header")
  .name("Authorization")
  .modelRef(new ModelRef("string"))
  .build();

将其添加到Docket配置:

return new Docket(DocumentationType.SWAGGER_2)
    .select()
    .apis(...)
    .paths(...)
    .build()
    .apiInfo(...)
    .globalOperationParameters(Collections.singletonList(authHeader));

它看起来像这样:

将 SpringDoc 与 springdoc-openapi-maven-plugin 一起使用我的选择是使用 SwaggerConfig.Java:

@Configuration
public class SwaggerConfiguration  {
    @Bean
    public OpenAPI customOpenAPI(@Value("${project.version}") String appVersion) {
        OpenAPI openApi = new OpenAPI();
                openApi.info(
                    new Info()
                .title("Title Example")
                .version(appVersion)
                .description("Swagger server created using springdocs - a library for OpenAPI 3 with spring boot.")
                );

                openApi.components(
                        new Components().addSecuritySchemes("bearer-jwt",
                new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
                        .in(SecurityScheme.In.HEADER).name("Authorization"))
                );

                openApi.addSecurityItem(
                        new SecurityRequirement().addList("bearer-jwt", Arrays.asList("read", "write"))
                );

        return openApi;
    }
}