在APIFlask ,怎么生成openid and oauth2 security scheme

我怎么能让 openapi.json 和 openapi.yaml 自动生存下面两个 security scheme, 这样我如果导入 openapi.json or openapi.yaml的时候,我的程序能知道有这两个security auth。

 securitySchemes:
    OpenID:
      type: openIdConnect
      openIdConnectUrl: https://login.microsoftonline.com/2ed2c5df-19e7-4-bfb7-eb26560fb1cc/v2.0/.well-known/openid-configuration
    OAuth2:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://login.microsoftonline.com/2ed2c5df-19e7-4eb-eb26560fb1cc/oauth2/v2.0/authorize
          scopes:
            openid: openid grant

谢谢!
我试了。但是不能用啊。下面是我的code和我的报错。

app.security_schemes = {
'OpenID': {
  'type': 'openIdConnect',
  'openIdConnectUrl': 'https://login.microsoftonline.com/2ed2c5df-19e7-4-bfb7-eb26560fb1cc/v2.0/.well-known/openid-configuration'
},
"OAuth2": {
    "type": "oauth2",
    "flows": {
        "implicit": {
            "authorizationUrl": "https://login.microsoftonline.com/2ed2c5df-19e7-4-bfb7-eb26560fb1cc/oauth2/v2.0/authorize",
            "scopes": {
                "openid": "openid grant"
            }
        }
    }
}
}



@app.get('/openidtest')
@app.doc(security='OpenID')
def open_id_test():
    return {'message': 'Hello!'}


[2022-05-09 10:35:55,432] ERROR in app: Exception on /openapi.json [GET]
Traceback (most recent call last):
  File "/home/user/.local/lib/python3.8/site-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/user/.local/lib/python3.8/site-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/user/.local/lib/python3.8/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 418, in dispatch_request
    return view_function(*req.view_args.values())  # type: ignore
  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 556, in spec
    response = jsonify(self._get_spec('json'))
  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 627, in _get_spec
    self._spec = self._generate_spec().to_dict()
  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 1123, in _generate_spec
    security[view_func_auth]: view_func._spec['roles']
UnboundLocalError: local variable 'security' referenced before assignment
127.0.0.1 - - [09/May/2022 10:35:55] "GET /openapi.json HTTP/1.1" 500 -

问题好像就是出在这里。我什么都不做,就是加了下面这几行,就报错了。

app = APIFlask(__name__)
app.security_schemes ={
    "OpenID": {
        "type": "openIdConnect",
        "openIdConnectUrl": "https://login.microsoftonline.com/2ed2c5df-19e7-4-bfb7-eb26560fb1cc//v2.0/.well-known/openid-configuration"
    }
    }

  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 1123, in _generate_spec
    security[view_func_auth]: view_func._spec['roles']
UnboundLocalError: local variable 'security' referenced before assignment

我另外还试了“ This attribute can also be configured from the config with the SECURITY_SCHEMES configuration key.“

app.config['SECURITY_SCHEMES'] = {"apikeyAuth":{"type": "apiKey", "in": "header", "name": "X-API-Key"}}

还是有错。

  File "/home/user/.local/lib/python3.8/site-packages/apiflask/app.py", line 1123, in _generate_spec
    security[view_func_auth]: view_func._spec['roles']
UnboundLocalError: local variable 'security' referenced before assignment
127.0.0.1 - - [09/May/2022 15:11:11] "GET /openapi.yaml HTTP/1.1" 500 -

这是你的完整代码吗?看起来似乎你混用了 app.auth_requiredapp.doc(security=...)

我已经知道问题在哪里了。应该是个APIFlask bug 对吗?
下面是我完整代码。你可以直接copy paste 到你的IDE, 试一试。
我用HTTPTokenAuth 做了一个API Key, 然后用 app.security_schemes 做了一个OpenID.
我用app.auth_required assign API Key 给一个path, 然后用app.doc assign OpenID 给另外一个path,
这种情况就会报错。APIFlask应该支持这种情况对吗?

from apiflask import APIFlask,HTTPTokenAuth


#API Key
apikey = HTTPTokenAuth(scheme='ApiKey', header='X-API-Key')
apikeys = {"123": "123",
           "456":"456"}

@apikey.verify_token
def verify_apikey(apikey):
    if apikey in apikeys:
        return apikeys[apikey]


app = APIFlask(__name__)

#Outh2
app.security_schemes = {
'OpenID': {
  'type': 'openIdConnect',
  'openIdConnectUrl': 'https://login.microsoftonline.com/68ff8/v2.0/.well-known/openid-configuration'
}
}

@app.get('/outh2test')
@app.doc(security='OAuth2')
def ouath2test():
    print ("hello")


@app.get('/apikeytest')
@app.auth_required(apikey)
def apikeytest():
    print ("hello")

目前的设计是要么用内置的 auth 功能,要么用外部的 auth 库。后续会考虑支持同时混用两者(https://github.com/apiflask/apiflask/issues/293)。感谢反馈。

Hello,1.0.2 版本添加了对这个功能的支持,现在可以再试试。

pip install -U apiflask

我需要改我的code吗?
还是 update apisky后就直接能用?

理论上是不需要改动。不妨先更新 APIFlask,然后执行程序试一下