每当我跑步时
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 秒偏差。有办法解决这个问题吗?
这就是 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 打开了一个 问题,并创建了一个相应的 拉取请求 ,因为我已经查看了所有源文件......
如果合并拉取请求,则服务器的时钟最多允许偏差一分钟。
我在 Windows 11 PC 中运行 localhost 时遇到了同样的问题。我通过转到控制面板 > 日期和时间 > Internet 时间并将同步服务器更改为 time.google.com 找到了临时解决方案。如果重新打开我的机器后错误仍然存在,请转到设置中的日期和时间并在其他设置上按立即同步,修复它直到机器关闭。
有类似的问题,通过在验证定义中添加“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"`
我看到这仍然没有被拉动。为了帮我解决这个问题,我执行了以下操作,以便它会在正确的时间重新尝试验证令牌。
@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)
转到
verify_id_token()
中的auth.py
功能并将clock_skew_seconds=0
更改为clock_skew_seconds=60
。对我来说效果很好。