使用以下JavaScript代码,我请求获取firebase令牌,然后使用JavaScript fetch()
方法向FastAPI后端发出POST
请求,以便用户登录,然后在后端(如下所示)检查令牌是否有效,如果有效,则返回重定向(即RedirectResponse
)到另一个网页,问题是浏览器中的重定向不起作用,上一页仍然存在。
function loginGoogle() {
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth()
//.currentUser.getToken(provider)
.signInWithPopup(provider)
.then((result) => {
/** @type {firebase.auth.OAuthCredential} */
var credential = result.credential;
// This gives you a Google Access Token. You can use it to access the Google API.
var token = credential.idToken;
// The signed-in user info.
var user = result.user;
// ...
})
.catch((error) => {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
firebase.auth().currentUser.getIdToken(true).then(function(idToken) {
console.log(idToken)
const token = idToken;
const headers = new Headers({
'x-auth-token': token
});
const request = new Request('http://localhost:8000/login', {
method: 'POST',
headers: headers
});
fetch(request)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
})
返回登录页面的后端端点,该页面包含带有按钮和loginGoogle
函数的HTML代码:
@router.get("/entrar")
def login(request: Request):
return templates.TemplateResponse("login.html", {"request": request})
我称之为POST
端点,然后重定向到/1
,这是一个GET
路由,status_code
是303
,这就是@tiangolo在文档中指定它从POST
重定向到GET
路由的方式。
@router.post("/login")
async def login(x_auth_token: str = Header(None)):
valid_token = auth.verify_id_token(x_auth_token)
if valid_token:
print("token validado")
return RedirectResponse(url="/1", status_code=status.HTTP_303_SEE_OTHER)
else:
return {"msg": "Token no recibido"}
这是用户应该重定向到的GET
端点,但它没有:
@app.get("/1")
def get_landing(request: Request):
return templates.TemplateResponse("landing.html", {"request": request})
测试/login
终点的Swagger屏幕截图:
2条答案
按热度按时间aoyhnmkz1#
我看到的可能导致这不起作用的主要“问题”是从Post请求到Get请求的速度太快。
在网上搜索了一下之后,我偶然发现了这个[BUG] RedirectResponse from a POST request route to GET request route,如果你读到这个bug,你会看到他们指定有时你可能需要一个307,而不是你可以在这里读到关于307响应的307 Temporary Redirect。
根据这一点,以下内容应有所帮助:
据我所知,这里的解决方案是使用
status_code=status.HTTP_302_FOUND
,您可以在这里了解更多信息:What Is a 302 Status Code?您也可以参考以下链接了解更多信息:
1.重定向响应
根据评论中的@Chris,你还有以下几点:
7vhp5slm2#
选项1-返回
RedirectResponse
当使用
fetch()
向服务器发出HTTP请求,而服务器以RedirectResponse
响应时,重定向响应将在客户端自动执行(如here所述),因为fetch()
方法中redirect
模式默认设置为follow
,这意味着用户不会被重定向到新的URL。而fetch()
将在幕后跟踪该重定向并返回重定向URL的响应。您可能希望将redirect
设置为manual
将允许您获取重定向URL(包含在Location
响应头中)并手动导航到新页面,但事实并非如此,如here所述。但是,您仍然可以在
fetch()
请求中使用默认的redirect
值,即follow
(不需要手动指定,因为已经默认设置了它-在下面的示例中,仅为了清楚起见手动定义它),然后使用Response.redirected
检查响应是否是您所做的重定向请求的结果。如果是,则可以使用Response.url
,这将返回 "在任何重定向之后获得的最终URL",并且使用JavaScript的window.location.href
,您可以将用户重定向到目标URL(即重定向页面)。除了
window.location.href
,用户还可以使用window.location.replace()
。与设置href
属性值的区别在于,当使用location.replace()
方法时,在导航到给定的URL后,当前页面不会保存在会话history中-这意味着用户将无法使用后退按钮导航到它。工作示例
模板/索引. html
选项2-返回包含重定向URL的JSON响应
您可以让服务器返回一个普通的JSON响应,并将URL包含在JSON对象中,而不是从服务器返回一个
RedirectResponse
。在客户端,您可以检查服务器返回的JSON对象(作为fetch()
请求的结果)是否包含url
键,如果包含,则检索其值并将用户重定向到目标URL。使用JavaScript的window.location.href
或window.location.replace()
。或者,可以将重定向URL添加到服务器端的自定义response header(参见示例here和here,了解如何在FastAPI中设置响应头),并在使用
fetch()
发布请求后在客户端访问它,如下所示(请注意,如果您正在执行cross-origin请求,则必须在服务器端设置Access-Control-Expose-Headers
响应头(参见示例here和here,以及FastAPI关于如何使用expose_headers
参数的CORSMiddleware
文档),指出您的自定义响应头(包括重定向URL)应该对浏览器中运行的JS脚本可用,因为默认情况下只公开CORS-safelisted response headers)。工作示例
模板/索引. html
选项3-在前端使用HTML
<form>
如果您的项目不需要使用
fetch()
请求,您可以使用普通的HTML<form>
,让用户单击submit
按钮将POST
请求发送到服务器。在服务器端使用RedirectResponse
(如选项1所示)将导致客户端的用户自动重定向到目标URL,而无需任何进一步的操作。