【问题标题】:Cross domain state cookie issue with proxied Firebase Functions代理 Firebase 函数的跨域状态 cookie 问题
【发布时间】:2020-11-06 09:41:30
【问题描述】:

我使用this example 开发了一个oAuth 登录。遇到的第一个问题是如果在浏览器中禁用了第三方 cookie(现在默认情况下),则状态 cookie 验证。正如this answer 所建议的,我代理了这些函数。

所以我使用 Hosting rewrites 代理了这些函数,所以你在同一个域中,并且第一个重定向函数设置的服务器 cookie 似乎与应用程序在同一个域中。这就是发生的事情

  1. 用户被重定向到设置 cookie 并将用户重定向到第三方身份验证提供商的云功能
  2. 用户登录
  3. 用户再次被重定向到应用程序,应用程序获取授权码并将用户重定向到令牌功能
  4. token函数尝试读取状态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,则代码可以正常工作。

【问题讨论】:

  • 您能确认您没有任何 CORS 策略错误吗?

标签: firebase oauth google-cloud-functions cross-domain


【解决方案1】:

您可能无意中发现了 Firebase 托管中的缓存功能,该功能可以去除除 __session 之外的所有 cookie。

将 Firebase 托管与 Cloud Functions 或 Cloud 一起使用时 运行,cookie 通常从传入的请求中剥离。这是 允许有效的 CDN 缓存行为所必需的。只有 允许特殊命名的 __session cookie 传递到 执行您的应用程序。

Source

尝试将您的 cookie 重命名为 __session,看看是否可以解决问题。

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 2011-02-25
    • 2011-02-12
    • 2021-04-07
    • 2012-04-11
    • 2014-09-28
    • 2014-04-01
    • 2015-12-23
    • 2019-08-22
    相关资源
    最近更新 更多