【发布时间】:2021-01-03 04:25:52
【问题描述】:
我正在尝试使用 FastAPI 为我们的组织创建一个 API。它有一个用于所有身份验证的 KeyCloak 服务器,以及被认为是最佳实践的 OpenID Connect 和 JWT。
在最简单的情况下,其他人负责获取有效的 JWT 令牌,以便 FastAPI 可以简单地解码和读取用户和权限。
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
jwt_token = jwt.decode(token, key=env.keycloak_server_public_key, audience='myorg')
return jwt_token['preferred_username']
except jwt.exceptions.ExpiredSignatureError:
raise credentials_exception
生活很简单!
不过,我确实想让用户使用 Swagger 页面探索 API。我创建了这个功能,让用户可以使用 UI 登录:
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
login_request = requests.post(
"https://mygreatorg.com/auth/realms/master/protocol/openid-connect/token",
data={
"grant_type": "password",
"username": form_data.username,
"password": form_data.password,
"client_id": "fastapi-application",
},
)
raw_response = json.loads(login_request.content.decode('utf-8'))
raw_response['acquire_time'] = time.time()
TOKEN_CACHE[form_data.username] = raw_response
return {"access_token": raw_response['access_token'], "token_type": "bearer"}
这很好用。 Swagger 中的 auth 标头现在是令牌,它会验证大约一分钟。令牌的过期时间设置为非常短的时间。然后预计使用raw_response 有效负载中提供的 refresh_token 刷新它们。
在给定 refresh_token 的情况下,我可以很容易地发出另一个请求以获取新的有效访问令牌。但我无法让 Swagger 在 UI 中更改请求的令牌。我发现的唯一方法是注销并重新登录,但如果他们只允许一分钟而不被踢出,用户会非常恼火。
一种解决方法是简单地缓存令牌并忽略过期时间,让用户登录一段时间,但这违背了整个安全设置的目的,感觉是个坏主意。
关于如何让 FastAPI 的 UI 在需要刷新时更新不记名令牌而不让用户再次登录的任何想法?
【问题讨论】:
-
你找到解决办法了吗?
-
我还没有找到解决这个问题的方法,但是自从我在发布问题后不久就离开了工作场所以来,我一直没有积极寻找。
-
我之前已经实现了类似的东西,你能否给我更多关于你可以访问的 API 端点的信息。比如
/token/grant_type: refresh_token等等。我之前没用过Open ID,如果你能指点我一些阅读材料,我可以帮你看看它 -
这个issue很好的描述了这个问题。 github.com/swagger-api/swagger-ui/issues/7257
-
你试过
return login_request.json()。登录请求应该带有一个刷新令牌,没有它你不能刷新 access_token。
标签: python jwt swagger swagger-ui fastapi