firebase_admin auth 的 verify_id_token 方法引发的令牌使用过早错误

问题描述 投票:0回答:5

每当我跑步时

from firebase_admin import auth
auth.verify_id_token(firebase_auth_token)

它抛出以下错误:

Token used too early, 1650302066 < 1650302067. Check that your computer's clock is set correctly.

我知道底层的 google auth API 会检查令牌的时间,但是如here所述,应该有 10 秒的时钟偏差。显然,我的服务器时间晚了 1 秒,但是运行仍然失败,即使这远低于允许的 10 秒偏差。有办法解决这个问题吗?

python firebase google-authentication
5个回答
17
投票

这就是 firebase_admin.verify_id_token 验证令牌的方式:

verified_claims = google.oauth2.id_token.verify_token(
                    token,
                    request=request,
                    audience=self.project_id,
                    certs_url=self.cert_url)

这是 google.oauth2.id_token.verify_token(...) 的定义

def verify_token(
    id_token,
    request,
    audience=None,
    certs_url=_GOOGLE_OAUTH2_CERTS_URL,
    clock_skew_in_seconds=0,
):

如您所见,函数 verify_token 允许指定“clock_skew_in_seconds”,但 firebase_admin 函数没有传递它,因此使用默认值 0,并且由于您的服务器时钟关闭了 1 秒,verify_token 中的检查失败.

我认为这是 firebase_admin.verify_id_token 中的一个错误,也许您可以针对 firebase admin SDK 提出问题,但除此之外,您只能确保您的时钟准确或显示的时间早于实际时间

编辑:

实际上,我在 GitHub 上为 firebase/firebase-admin-Python 打开了一个 问题,并创建了一个相应的 拉取请求 ,因为我已经查看了所有源文件......

如果合并拉取请求,则服务器的时钟最多允许偏差一分钟。


3
投票

我在 Windows 11 PC 中运行 localhost 时遇到了同样的问题。我通过转到控制面板 > 日期和时间 > Internet 时间并将同步服务器更改为 time.google.com 找到了临时解决方案。如果重新打开我的机器后错误仍然存在,请转到设置中的日期和时间并在其他设置上按立即同步,修复它直到机器关闭。


2
投票

有类似的问题,通过在验证定义中添加“clock_skew_in_seconds=10”来解决它`

   def validate(auth_token):
    """
    validate method Queries the Google oAUTH2 api to fetch the user info
    """
    try:
        idinfo = id_token.verify_oauth2_token(
            auth_token, requests.Request(), clock_skew_in_seconds=10)

        if 'accounts.google.com' in idinfo['iss']:
            return idinfo

    except:
        return "The token is either invalid or has expired"`

0
投票

我看到这仍然没有被拉动。为了帮我解决这个问题,我执行了以下操作,以便它会在正确的时间重新尝试验证令牌。

@staticmethod
def decode_token(id_token: str) -> FirebaseToken:
    """Decode a Firebase ID token.

    Args:
        id_token (str): A valid Firebase `id_token`, this will be checked to determine if:
            * The token is present and a valid JWT.
            * The token has NOT expired.
            * The token has NOT been revoked.
            * The token has been issued under the correct GCP credentials (API key).

    Returns:
        FirebaseToken: A serialized Firebase ID token.

    Raises:
        HTTPException: If the token fails it's validation.
    """
    try:
        
        payload = JWTBearer.verify_token(id_token)
    except ValueError as err:
        raise HTTPException(
            status_code=401, detail="Unable to verify token"
        ) from err
    except (
        ExpiredIdTokenError,
        InvalidIdTokenError,
        RevokedIdTokenError,
    ) as err:
        # this happens on localhost all the time.
        str_err = str(err)
        if (str_err.find("Token used too early") > -1):
            times = str_err.split(",")[1].split("<")
            time = int(times[1]) - int(times[0])
            sleep(time)
            return JWTBearer.decode_token(id_token)
        raise HTTPException(
            status_code=403, detail=err.default_message
        ) from err
    except CertificateFetchError as err:
        raise HTTPException(
            status_code=500,
            detail="Failed to fetch public key certificates",
        ) from err

    return FirebaseToken(**payload)

0
投票

转到

verify_id_token()
中的
auth.py
功能并将
clock_skew_seconds=0
更改为
clock_skew_seconds=60
。对我来说效果很好。

© www.soinside.com 2019 - 2024. All rights reserved.