firebase - 代理 Firebase 函数的跨域状态 cookie 问题
问题描述
我使用这个例子开发了一个 oAuth 登录。遇到的第一个问题是如果在浏览器中禁用了第三方 cookie(现在默认情况下),则状态 cookie 验证。正如这个答案所建议的,我代理了这些功能。
所以我使用 Hosting rewrites 代理了这些函数,所以你在同一个域中,并且第一个重定向函数设置的服务器 cookie 似乎与应用程序在同一个域中。所以这就是发生的事情
- 用户被重定向到设置 cookie 并将用户重定向到第三方身份验证提供程序的云功能
- 用户登录
- 用户再次被重定向到应用程序,应用程序获取授权码并将用户重定向到令牌功能
- 令牌函数尝试读取状态cookie,但根本没有cookie
当我尝试从令牌函数中读取 cookie 时
[Object: null prototype] {}
这是主机重写
"hosting": {
...
"rewrites": [
{
"source": "/redirect",
"function": "redirect"
},
{
"source": "/token**",
"function": "token"
},
{
"source": "**",
"destination": "/index.html"
}
],
这是重定向功能
exports.redirect = functions.https.onRequest((req, res) => {
cookieParser()(req, res, () => {
const redirect_uri = `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com/auth.html`
const state = req.cookies.state || crypto.randomBytes(20).toString('hex')
const authorizationUri = fedidClient().authorizationCode.authorizeURL({
redirect_uri: redirect_uri,
scope: OAUTH_SCOPES,
state: state,
})
res.cookie('state', state.toString(), {
maxAge: 3600000,
secure: true,
httpOnly: true,
})
res.redirect(authorizationUri)
})
})
这是令牌功能
exports.token = functions.https.onRequest((req, res) => {
const redirect_uri = `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com/auth.html`
try {
return cookieParser()(req, res, async () => {
if (!req.cookies.state) {
throw new Error(
'State cookie not set or expired. Maybe you took too long to authorize. Please try again.'
)
}
const tokenConfig = {
code: req.query.code,
redirect_uri: redirect_uri,
scope: OAUTH_SCOPES,
}
const result = await fedidClient().authorizationCode.getToken(tokenConfig)
const accessToken = fedidClient().accessToken.create(result)
let user = {}
await getUserInfo(accessToken)
.then((result) => result.json())
.then((json) => (user = json))
// Create a Firebase account and get the Custom Auth Token.
const firebaseToken = await createFirebaseAccount(
user.uid,
user.displayName,
user.mail,
accessToken.token.access_token
)
res.jsonp({
token: firebaseToken,
})
})
} catch (error) {
return res.status(500).jsonp({ error: error.toString })
}
})
为什么cookie没有通过第二个云函数?如果禁用重写并启用第三方 cookie,则代码可以正常工作。
解决方案
您可能无意中发现了 Firebase 托管中的缓存功能,该功能可以去除除__session
.
将 Firebase 托管与 Cloud Functions 或 Cloud Run 一起使用时,通常会从传入请求中删除 cookie。这对于允许有效的 CDN 缓存行为是必要的。只有特别命名的 __session cookie 被允许传递给您的应用程序的执行。
尝试将您的 cookie 重命名为 __session 并查看是否可以修复它。
推荐阅读
- java - NavigatorView 中每个项目的 OnBackPressed
- elasticsearch - 无法启动 Elasticsearch (code=killed, signal=KILL)
- javascript - 字母数字字符串中带有可选点的正则表达式
- javascript - 数组未返回预期输出
- python - python在数据框中查找特定值
- excel-formula - 是否有一个excel函数计算可变利率下固定付款的未来价值
- css - 颜色变化,主要悬停
- javascript - 单击停止时如何在表单中提交计时器值?
- r - 安排 R 地块:如何安排 VIM 包的地块?
- python - 如何在 GUI 中绘制 DENDROGRAM