如何在Swagger规范中使用'Authorization: Bearer <token>'?

173
我试图传达的是,身份验证/安全方案需要设置一个头部,如下所示:
Authorization: Bearer <token>

这是我根据swagger文档所得出的内容:
securityDefinitions:
  APIKey:
    type: apiKey
    name: Authorization
    in: header
security:
  - APIKey: []
7个回答

190

也许这可以帮助:

swagger: '2.0'
info:
  version: 1.0.0
  title: Bearer auth example
  description: >
    An example for how to use Bearer Auth with OpenAPI / Swagger 2.0.

host: basic-auth-server.herokuapp.com
schemes:
  - http
  - https
securityDefinitions:
  Bearer:
    type: apiKey
    name: Authorization
    in: header
    description: >-
      Enter the token with the `Bearer: ` prefix, e.g. "Bearer abcde12345".
paths:
  /:
    get:
      security:
        - Bearer: []
      responses:
        '200':
          description: 'Will send `Authenticated`'
        '403': 
          description: 'You do not have necessary permissions for the resource'

你可以将其复制并粘贴到https://editor.swagger.io,以查看结果。

Swagger Editor网页中还有一些具有更复杂安全配置的示例,这可能对您有所帮助。

重要提示: 在此示例中,API使用者必须将"Bearer"前缀包含在令牌值中。例如,在使用Swagger UI的"授权"对话框时,您需要输入Bearer your_token而不是仅输入your_token

Swagger UI's Authorization dialog


4
我不明白你如何告诉编辑器要发送哪个用户、密码或基本令牌,以便获得 200 的状态码。我是否遗漏了什么? - Rob
1
好的,没关系。显然,“Authenticate”是可以点击的,以获取登录表单。 - Rob
2
@Gobliins 您需要使用curl -X GET -H "Authorization: Bearer your_token",其中 your_token 是您的令牌。例如:curl -X GET -H "Accept: application/json" -H "Authorization: Bearer 00000000-0000-0000-0000-000000000000" "http://localhost/secure-endpoint" - Steve K
26
很不幸,这种方法在Swagger UI中效果不佳—— 点击“授权”并提供裸令牌将生成带有-H "Authorization: foo"而不是像OpenAPI 3答案那样的-H "Authorization: Bearer foo"的“试一下”curl示例。 - Abe Voelker
5
对我来说,解决方法是在 UI 授权框中将 Bearer xxxxxxxx 作为密钥。这样做有效,但缺点是需要告诉用户手动输入 Bearer 和密钥。或者,您可以修改返回 API 密钥的函数/方法,以使 Bearer 前缀成为密钥的一部分。 - csteel
显示剩余4条评论

106

在OpenAPI 3.x中使用Bearer验证

OpenAPI 3.0及以上版本本地支持Bearer/JWT验证。其定义如下:

openapi: 3.0.0
...

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT  # optional, for documentation purposes only

security:
  - bearerAuth: []

Swagger UI 3.4.0+ 和 Swagger Editor 3.1.12+(仅适用于 OpenAPI 3.x 规范!)支持此功能。

UI 将显示“授权”按钮,您可以单击并输入令牌(仅令牌本身,不包括前缀“Bearer ”)。之后,“试一试”请求将带有 Authorization: Bearer xxxxxx 标头。

编程方式添加Authorization 标头 (Swagger UI 3.x+)

如果您使用 Swagger UI 并且出于某种原因需要以编程方式添加Authorization标头而不是让用户单击“授权”并输入令牌,则可以使用 requestInterceptor。这个解决方案适用于 Swagger UI 3.x+;UI 2.x 使用了不同的技术。

// index.html

const ui = SwaggerUIBundle({
  url: "https://your.server.com/swagger.json",
  ...

  requestInterceptor: (req) => {
    req.headers.Authorization = "Bearer xxxxxxx"
    return req
  }
})

2
我该如何在Flask-RestPlus生成的Swagger文档中实现这个功能? - Chang Zhao
我怀疑答案是否符合所提出的问题。 - Vishrant
通过这样做,我得到了“没有路由匹配”的错误。 - Humayun Naseer
2
这个对我有用,文档在这里:https://swagger.io/docs/specification/authentication/bearer-authentication/ - TalesMGodois
有没有办法在Swagger UI中以编程方式添加令牌?requestInterceptor似乎无法正常工作。 - RoRFan

37

使用 OpenAPI 3.0.0 将 2023 年的答案以 JSON 形式发布:

{
  "openapi": "3.0.0",
  ...
  "servers": [
    {
      "url": "/"
    }
  ],
  ...
  "paths": {
    "/skills": {
      "put": {
        "security": [
           {
              "bearerAuth": []
           }
        ],
       ...
  },


  "components": {        
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}

1
运行得非常好 :-)) - Naren
1
阅读 Swagger 文档时,我无法确定此方案中的令牌端点在哪里。 - Kakash1hatake
@Kakash1hatake,你需要将它作为一个带有两个参数(用户名、密码)的GET请求添加。响应将是令牌。 - Vitaly Sazanovich
@vitaly-sazanovich 不,你没有看到重点。当模式为oauth2时,它有专门的authorizationUrl参数来保存获取令牌的端点地址。而bearer模式则缺少此参数。但我认为它是与外部身份提供者一起使用的,因此令牌是在那里生成的。 - Kakash1hatake

21

为什么“已接受的答案”有效,但对我来说还不够

在规范中,这是可行的。至少swagger-tools(版本0.10.1)将其验证为有效。

但是如果您使用其他工具,例如swagger-codegen(版本2.1.6),即使生成的客户端包含身份验证定义,您也会遇到一些困难,例如:

this.authentications = {
  'Bearer': {type: 'apiKey', 'in': 'header', name: 'Authorization'}
};

在调用 method(endpoint) 之前无法将令牌传递到标头中。请查看此函数签名:

this.rootGet = function(callback) { ... }

这意味着,我只传递回调函数(在其他情况下是查询参数等),没有令牌,这导致向服务器的请求构建不正确。

我的替代方案

很遗憾,它不够“美观”,但在Swagger获得JWT令牌支持之前它可以使用。

注意:这正在讨论中

因此,它像标准标头一样处理身份验证。在path对象上附加一个头部参数:

swagger: '2.0'
info:
  version: 1.0.0
  title: Based on "Basic Auth Example"
  description: >
    An example for how to use Auth with Swagger.

host: localhost
schemes:
  - http
  - https
paths:
  /:
    get:
      parameters:
        - 
          name: authorization
          in: header
          type: string
          required: true
      responses:
        '200':
          description: 'Will send `Authenticated`'
        '403': 
          description: 'You do not have necessary permissions for the resource'

这将在方法签名中生成一个新的参数,用于生成客户端:

this.rootGet = function(authorization, callback) {
  // ...
  var headerParams = {
    'authorization': authorization
  };
  // ...
}

要正确使用这种方法,只需传递“完整字符串”

// 'token' and 'cb' comes from elsewhere
var header = 'Bearer ' + token;
sdk.rootGet(header, cb);

以及作品。


1
"token来自其他地方" ... 我对这个其他地方很感兴趣。当您登录并被重定向到您的登录和Swagger API时,您如何使用收到的访问令牌? - seawave_23

1
通过使用 requestInterceptor,对我很有效:
const ui = SwaggerUIBundle({
  ...
  requestInterceptor: (req) => {
    req.headers.Authorization = "Bearer " + req.headers.Authorization;
    return req;
  },
  ...
});

0

我的Hackie方法是通过修改echo-swagger包中的swagger.go文件来解决这个问题:

在文件底部更新window.onload函数,包括一个requestInterceptor,正确格式化令牌。

window.onload = function() {
  // Build a system
  const ui = SwaggerUIBundle({
  url: "{{.URL}}",
  dom_id: '#swagger-ui',
  validatorUrl: null,
  presets: [
    SwaggerUIBundle.presets.apis,
    SwaggerUIStandalonePreset
  ],
  plugins: [
    SwaggerUIBundle.plugins.DownloadUrl
  ,
  layout: "StandaloneLayout",
  requestInterceptor: (req) => {
    req.headers.Authorization = "Bearer " + req.headers.Authorization
  return req
  }
})

window.ui = ui

}


0

解决Laravel 7x ("openapi": "3.0.0")中的问题,编辑config\l5-swagger.php,并使用以下代码

'securityDefinitions' => [
                'securitySchemes' => [
                    'bearerAuth' => [ 
                        'type' => 'http',
                        'scheme' => 'bearer',
                        'bearerFormat' => 'JWT', 
                    ], 
                ],

然后,您可以将此作为安全注释添加到您的端点:

*security={
     *{
     *"bearerAuth": {}},
     *},

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接