Python中的Firebase身份验证令牌获取和使用Fast API的令牌验证


要做的事情

使用Firebase和FastAPI,在客户端获取令牌,在单击自己的API时将其粘贴在标头中,然后在服务器端进行验证以确定是否已登录。在这里,我们将使用Google制造的firebase_admin验证令牌。

获取令牌

在Firebase控制台的"身份验证"中启用密码登录,并如下创建一个合适的帐户。在这里,使用此登录。当然,可以使用Twitter之类的授权。

1
2
EMAIL = '[email protected]'
PASSWORD = 'password'

安装所需的内容。

1
$ pip install requests

从firebase控制台获取以下JSON并将其粘贴以使其看起来不错。 (实际上仅使用apiKey)

1
2
3
4
5
6
7
8
9
10
CONFIG = {
    "apiKey": "YOUR API KEY",
    "authDomain": "YOURPROJECTID.firebaseapp.com",
    "databaseURL": "https://YOURPROJECTID.firebaseio.com",
    "projectId": "YOUR PROJECT ID",
    "storageBucket": "YOUR PROJECT ID.appspot.com",
    "messagingSenderId": "YOUR MESSAGE SENDER ID",
    "appId": "YOUR:APP:ID",
    "measurementId": "YOUR MEASUREMENT ID"
}

点击Firebase Auth的REST API以获得令牌。 REST API文档在这里。

1
2
3
4
5
6
7
api_key = CONFIG["apiKey"]
uri = f"https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key={api_key}"
data = {"email": EMAIL, "password": PASSWORD, "returnSecureToken": True}

result = requests.post(url=uri, data=data).json()

token = result['idToken']

该令牌在运行时输出,稍后将使用。

使用FastAPI验证令牌

安装所需的内容。

1
$ pip install fastapi firebase_admin uvicorn

在Firebase控制台中,转到Gear→服务帐户→生成新私钥以下载并加载私钥。

1
2
3
4
from firebase_admin import auth, credentials

cred = credentials.Certificate("path/to/cert.json")
firebase_admin.initialize_app(cred)

定义一个函数,该函数从

标头中获取令牌,对其进行解码并获取用户信息。
实际上,我认为您可以在此处从数据库中获取用户信息。
FastAPI文档提供了一个使用fastapi.security.OAuth2PasswordBearer的示例,但是它没有描述如何简单地获取Bearer令牌,我不得不看一下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends, HTTPException, status

def get_current_user(cred: HTTPAuthorizationCredentials = Depends(HTTPBearer())):
    try:
        decoded_token = auth.verify_id_token(cred.credentials)
    except:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail='Invalid authentication credentials',
            headers={'WWW-Authenticate': 'Bearer'},
        )

    user = decoded_token['firebase']['identities']

    return user

定义只能使用有效Bearer令牌访问的端点。
FastAPI真的很有用,因为您可以使用Depends和类型注释来注入所需的内容。

1
2
3
4
5
6
7
8
9
10
11
12
from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()

@app.get('/')
async def homepage(current_user=Depends(get_current_user)):
    return {'msg': 'ok', 'user': current_user}

if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app, host='localhost', port=5000)

执行

到目前为止的代码在Gist中进行了总结。
首先,使用下面的代码获取令牌并将其复制。
https://gist.github.com/pteroid/241687ecb5219ae0ce633a884d8ab5bb

接下来,使用以下代码启动服务器。
https://gist.github.com/pteroid/a698fd679fb545cb2cfe792f0114938c

使用合适的REST客户端(我使用Insomnia)将其选中。然后,您将获得以下结果。

请求

1
2
3
4
5
6
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: insomnia/7.1.1
> Authorization: Bearer
YOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKENYOURTOKEN
> Accept: */*

响应

1
2
3
4
5
6
7
8
9
10
11
{
  "msg": "ok",
  "user": {
    "identities": {
      "email": [
        "[email protected]"
      ]
    },
    "sign_in_provider": "password"
  }
}

最后

FastAPI我希望您变得更受欢迎。