登录后仅在Swagger中显示用户可用的端点

时间:2019-12-26 08:01:57

标签: swagger swagger-ui

我想设置后续工作流程:

  1. 最初,无需登录,Swagger仅显示2-3个端点-这将通过从后端提供有限的openapi3 json来完成,没问题;
  2. 用户通过“授权”按钮登录(有效,openapi3 json具有必要的信息);
  3. 登录后,Swagger会发出另一个带有用户凭据的请求,后端会提供新的openapi3 json,该端点可用于此特定用户,而Swagger会用新数据重绘页面。最好仍是用户登录。

可以用Swagger进行第3项吗?如何使用OAuth2不记名令牌从Swagger手动发出请求(自从用户登录以来,令牌必须出现在某处)并重新绘制Swagger页面?

1 个答案:

答案 0 :(得分:0)

该任务是通过使用其plugin system的Swagger定制完成的。
实际上Swagger是一个使用React / Redux的JavaScript(Babel,Webpack)项目,由于我不知道React(我的工具是Python),但是最终还是我管理,所以很难深入研究它。
这是带有注释的自定义插件的代码:

    const AuthorizedPlugin = function(system) {
      return {
        statePlugins: {
          auth: {  // namespace for authentication subsystem
            // last components invoked after authorization or logout are
            // so-called reducers, exactly they are responsible for page redraw
            reducers: {
              "authorize_oauth2": function(state, action) {
                let { auth, token } = action.payload
                let parsedAuth

                auth.token = Object.assign({}, token)
                parsedAuth = system.Im.fromJS(auth)

                var req = {
                  credentials: 'same-origin',
                  headers: {
                    accept: "application/json",
                    Authorization: "Bearer " + auth.token.access_token
                  },
                  method: 'GET',
                  url: system.specSelectors.url()
                }
                // this is the additional request with token I mentioned in the question
                system.fn.fetch(req).then(
                  function (result) {
                    // ... and we just call updateSpec with new openapi json
                    system.specActions.updateSpec(result.text)
                  }
                )

                // This line is from the original Swagger-ui code
                return state.setIn( [ "authorized", parsedAuth.get("name") ], parsedAuth )
              },
              "logout": function(state, action) {
                var req = {
                  credentials: 'same-origin',
                  headers: { accept: "application/json" },
                  method: 'GET',
                  url: system.specSelectors.url()
                }
                // for logout, request does not contain authorization token
                system.fn.fetch(req).then(
                  function (result) {
                    system.specActions.updateSpec(result.text)
                  }
                )
                // these lines are to make lock symbols gray and remove credentials
                var result = state.get("authorized").withMutations(function (authorized) {
                  action.payload.forEach(function (auth) {
                    authorized.delete(auth);
                  });
                });
                return state.set("authorized", result)
              }
            }
          }
        }

      }
    }

照常插入此插件:

        const ui = SwaggerUIBundle({{
        url: '{openapi_url}',
        dom_id: '#swagger-ui',
        defaultModelsExpandDepth: -1,
        displayOperationId: false,
        presets: [
            SwaggerUIBundle.presets.apis,
            SwaggerUIBundle.SwaggerUIStandalonePreset
        ],
        plugins: [
          AuthorizedPlugin
        ],
        layout: "BaseLayout",
        deepLinking: true
    })