简体   繁体   English

FastAPI:使用 firebase 令牌的安全性

[英]FastAPI: security with firebase token

I'm following this tutorial to create an api backend.我正在按照本教程创建一个 api 后端。

I use firebase authentication:我使用 firebase 身份验证:

  • user input email and password at frontend用户在前端输入 email 和密码
    • front sends the info to firebase前端将信息发送到 firebase
    • firebase auth user and return token firebase 授权用户并返回令牌
    • front stores the token前面存储令牌
  • for any url that needs auth, front sends the token in Authorization header ( Bearer xxx )对于任何需要身份验证的 url,前端在Authorization header( Bearer xxx )中发送令牌
  • server side firebase checks the token服务器端 firebase 检查令牌

The tutorial shows how to do this with a password:本教程展示了如何使用密码执行此操作:

# creating a dependency
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user

But since I'm using firebase, there is no /token for getting token with password.但是由于我使用的是 firebase,因此没有/token用于获取带密码的令牌。

I can parse the token by creating a custom dependency, like:我可以通过创建自定义依赖项来解析令牌,例如:

async def parse_token(auth_token:str = Header(...)):
    token = auth_token.split(' ')[1]
    return token

async def get_current_user(token: str = Depends(parse_token)):
    # check the token with firebase auth
    user = auth.verify_id_token(token)
    return user

But now I have to check everything and return exceptions manually.但现在我必须检查所有内容并手动返回异常。

Is there a FastAPI way to do this?有没有 FastAPI 方法可以做到这一点?

Simply ignore it.简单地忽略它。

The /token endpoint is used to authenticate and generate the token (on successful attempt). /token端点用于验证和生成令牌(成功尝试时)。 It's just a login page/form.它只是一个登录页面/表单。 You simply skip that part and use a dependency that will perform the check.您只需跳过该部分并使用将执行检查的依赖项。

Of course, you have to follow the same name and positioning of the OAuth2Password stuff.当然,您必须遵循OAuth2Password内容的相同名称和位置。

Remember, HTTP is stateless, and tokens are used to remember that a user has already provided identification.请记住,HTTP 是无状态的,令牌用于记住用户已经提供了身份证明。 If you have a valid token, you can also swap it on another machine and use it (unless there are some security cookies and machine-related information is stored within the cookie).如果你有一个有效的令牌,你也可以在另一台机器上交换它并使用它(除非有一些安全 cookie 并且与机器相关的信息存储在 cookie 中)。

If you go on with the tutorial that you linked, you'll get to the final code with the authentication.如果继续学习链接的教程,您将获得带有身份验证的最终代码。 Simply provide the firebase token in the "Authorization: Bearer {token}" of your requests from the frontend to the backend and it will work.只需在从前端到后端的请求的"Authorization: Bearer {token}"中提供 firebase 令牌,它就会起作用。

Below the link to the documentation.在文档链接下方。

https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/ https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/

I had similar use case and on googling I got to this question.我有类似的用例,在谷歌搜索时我遇到了这个问题。 But it was not of much help to me.但这对我没有太大帮助。 Upon further research I came across this post which was of much help.经过进一步研究,我发现了这篇很有帮助的文章 Just create a dependency as follows;只需按如下方式创建依赖项;

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends, HTTPException, status, Response
from firebase_admin import auth, credentials
import firebase_admin

cred = credentials.Certificate('./account_key.json')
firebase_admin.initialize_app(cred)

def get_user(res: Response, cred: HTTPAuthorizationCredentials=Depends(HTTPBearer(auto_error=False))):
    if cred is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Bearer authentication required",
            headers={'WWW-Authenticate': 'Bearer realm="auth_required"'},
        )
    try:
        decoded_token = auth.verify_id_token(cred.credentials)
    except Exception as err:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Invalid authentication credentials. {err}",
            headers={'WWW-Authenticate': 'Bearer error="invalid_token"'},
        )
    res.headers['WWW-Authenticate'] = 'Bearer realm="auth_required"'
    return decoded_token

Then add the dependency on the endpoints you would like to protect as follows然后添加对您要保护的端点的依赖,如下所示

async def hello_user(user = Depends(get_user))

This integrates nicely with Swagger endpoint and you can then receive idToken on your requests and just use them as you you wish.这与 Swagger 端点很好地集成,然后您可以根据您的请求接收idToken并根据需要使用它们。 Very much thanks to the poster非常感谢海报

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM