我正在尝试为我的 FARM 堆栈应用程序设置 Google OAuth。
我的问题是: 当我在本地运行应用程序时,我的流程和代码正在运行。 但它在生产中不起作用。 (因为如果我的 OAuth 应用程序设置为生产模式,Google 不允许我在“http”方案中输入重定向 URL。) 我满足了所有要求,例如 ClientID、重定向 URI。
这是我遵循的步骤:
1- 为 Web 应用程序创建了 ClientId。 2- 添加了所需的重定向 URI。 3- 在 FastAPI 中我有这段代码:
# config["CLIENT_URL"] equals to my React App's url.
@router.get('/google_cb') # 1
async def login(request: Request):
redirect_uri = request.url_for('google')
return await oauth.google.authorize_redirect(request, redirect_uri)
@router.get("/google", name="google") # 2
async def google_oauth(request: Request):
try:
access_token = await oauth.google.authorize_access_token(request)
user = user_service.find_one(
{"email": access_token['userinfo']['email'], "authentication_method": AuthenticationMethod.GOOGLE})
if user:
access_token_expires = timedelta(minutes=config["Auth"]["token_expiry"])
access_token = create_access_token(
data={"sub": user.id, "scopes": []},
expires_delta=access_token_expires,
)
return RedirectResponse(url=f'{config["CLIENT_URL"]}/oauthcb/' + access_token)
invite = invites_repository.find_one({"email": access_token['userinfo']['email'], "status": "Pending"})
if not invite:
raise HTTPException(status_code=404, detail="Invite not found")
created_user = user_service.create_user(
{"email": invite["email"], "hashed_password": "google_auth",
"tenant_id": invite["tenant_id"], "disabled": False, "first_name": access_token['userinfo']['given_name'],
"last_name": access_token['userinfo']['family_name'], "is_admin": False, "fireflies_id": None,
"authentication_method": "Google", "external_auth_data": access_token})
access_token_expires = timedelta(minutes=config["Auth"]["token_expiry"])
access_token = create_access_token(
data={"sub": str(created_user.inserted_id), "scopes": []},
expires_delta=access_token_expires,
)
invites_repository.delete({"_id": invite["_id"]})
return RedirectResponse(url=f'{config["CLIENT_URL"]}/oauthcb/' + access_token)
except OAuthError as e:
print(e)
return RedirectResponse(url=f'{config["CLIENT_URL"]}')
4- 在 React 中我有这段代码:
process.env.REACT_APP_API_URL is set to https://my.api.url
<Button
icon={<GoogleOutlined />}
onClick={() => {
window.location.replace(
`${process.env.REACT_APP_API_URL}/oauth/google_cb`
);
}}
>
Login with Google
</Button>
5- 流程:用户在 React App 中按下 Login With Google 按钮,用户点击后端的 https://my.api.url/google_cb 端点。后端将用户重定向到谷歌提供的页面以输入他们的电子邮件和密码。他们登录后,谷歌应该将用户重定向到 https://my.api.url/google 端点,我在这里完成我的过程。
问题是:虽然我将用户从 React 重定向到 https://my.api.endpoint/google_cb 我收到错误“redirect_url_mismatch”,错误中显示“redirect_url=http://my.api.endpoint/google_cb” 这导致了我的问题。我对此很确定,因为我将我的 OAuth 应用程序的模式从 Google 控制台切换到“生产”的“测试”并且它有效。
在生产模式下谷歌不允许我输入 http url。他们只是让我输入https。
但我非常确定我将用户重定向到 https 而不是 http。
我想知道以前是否有人遇到过同样的问题。
已解决,问题是 request.url_for 函数将 url 返回为“http”而不是“https”。
更新我的代码为:
async def login(request: Request):
redirect_uri = request.url_for('google')
if request.base_url.hostname == 'localhost':
# I consider about localhost for testing purposes, you may not have this.
redirect_uri = redirect_uri.replace('https', 'http')
else:
redirect_uri = redirect_uri.replace('http', 'https')
return await oauth.google.authorize_redirect(request, redirect_uri)
确保您的后端重定向到正确的 url!