【问题标题】:Firebase admin().auth().getUser(uid) internal errorFirebase admin().auth().getUser(uid) 内部错误
【发布时间】:2018-01-04 12:48:50
【问题描述】:

firebaseAdmin.auth().getUser(uid) 导致以下错误:

Error: An internal error has occurred. Raw server response: "{}"
    at FirebaseAuthError.FirebaseError [as constructor] (/home/nowuser/src/node_modules/firebase-admin/lib/utils/error.js:39:28)
    at new FirebaseAuthError (/home/nowuser/src/node_modules/firebase-admin/lib/utils/error.js:104:23)
    at Function.FirebaseAuthError.fromServerError (/home/nowuser/src/node_modules/firebase-admin/lib/utils/error.js:128:16)
    at /home/nowuser/src/node_modules/firebase-admin/lib/auth/auth-api-request.js:364:45
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:169:7)

当我在 Zeit Now 上部署到生产环境时,会发生此错误;当我在本地主机上以生产模式运行我的应用程序时,我没有收到此错误。我通过将应用程序放在 Docker 容器中来确保应用程序在本地和生产环境中运行相同。

我该如何解决这个错误?


注意:

我知道这个问题已经发布here,但接受的答案(更改服务帐户的权限)对我不起作用。此外,该问题并未显示收到的完整错误,因此我不相信这是完全相同的错误。


更新:以下是与此问题相关的代码。基本上,服务器启动一个快速服务器,它使用 POST authWithIdToken 路由来设置一个包含用户的 firebase auth idToken 的 cookie。它使用 authenticationMiddleware 来检查带有 idToken 的 cookie,如果存在,则解码该令牌并获取用户的数据。错误发生在 getUser(uid) 步骤。 getFirebaseAdminInitConfig 函数获取使用 ENV 变量提供的 init 配置。

# server.js - excerpt showing authentication middleware and authWithIdTokenRoute
const server = express()
# ...
allowParsingPostBody(server)
server.use(cookieParser())
server.use('*', authenticationMiddleware)
server.post('/authWithIdToken', authWithIdTokenRoute)
# ...



# authenticationMiddleware.js
const { FIREBASE_ID_TOKEN_COOKIE } = require('../universal/constants')
const firebaseAdmin = require('firebase-admin')
const winston = require('winston')
const getFirebaseAdminInitConfig = require('./getFirebaseAdminInitConfig')

winston.info(
  'Initializing Firebase Admin with Config:',
  getFirebaseAdminInitConfig()
)

firebaseAdmin.initializeApp(getFirebaseAdminInitConfig())

async function decodeToken (firebaseIdToken) {
  try {
    const decodedToken = await firebaseAdmin.auth().verifyIdToken(firebaseIdToken)
    return decodedToken
  } catch (error) {
    if (error.code !== 'auth/internal-error') throw error
    winston.warn(
      'firebase admin auth verifyIdToken auth/internal-error:',
      {
        firebaseIdToken,
        error
      }
    )
  }
}

const getFullUrl = (req) => (
  req.protocol + '://' + req.get('host') + req.originalUrl
)

const getRedirectUrl = (req) => (
  `/redirect?url=${encodeURIComponent(getFullUrl(req))}`
)

async function getUserData (uid) {
  try {
    const userData = await firebaseAdmin.auth().getUser(uid)
    return userData
  } catch (error) {
    if (error.code !== 'auth/internal-error') throw error
    winston.warn(
      'firebase admin auth getUser auth/internal-error:',
      {
        uid,
        error
      }
    )
  }
}

async function authenticationMiddleware (req, res, next) {
  const { firebaseIdToken } = req.cookies

  if (firebaseIdToken) {
    try {
      req.currentUserServerData = await getUserData(
        (await decodeToken(firebaseIdToken))
        .uid
      )
    } catch (error) {
      res.clearCookie(FIREBASE_ID_TOKEN_COOKIE)

      // if the cookie id token has expired, redirect the user to
      // /redirect?url={requestedUrl} - the client will try to set
      // a new cookie and then will redirect to requestedUrl
      if (error.code === 'auth/argument-error') {
        return res.redirect(getRedirectUrl(req))
      } else {
        winston.warn('Unexpected error occurred while processing firebase idToken:', error)
      }
    }
  }

  next()
}

authenticationMiddleware.authWithIdTokenRoute = async function ({body: { idToken }}, res) {
  try {
    await decodeToken(idToken)
    const expireDate = (new Date())
    expireDate.setYear((new Date()).getFullYear() + 1)
    res.cookie(FIREBASE_ID_TOKEN_COOKIE, idToken, { expires: expireDate })
    return res.send()
  } catch (error) {
    winston.warn('authWithIdTokenRoute unexpected error', {
      idToken,
      error
    })

    if (error.code === 'auth/argument-error') {
      return res
      .status(400)
      .send({
        error: new Error('Could not decode token')
      })
    } else {
      return res.status(500).send()
    }
  }
}

module.exports = authenticationMiddleware



# getFirebaseAdminInitConfig.js
const firebaseAdmin = require('firebase-admin')

// ENV variables are set in .env file and loaded by dotenv.
// See for more info: https://github.com/motdotla/dotenv
const getFirebaseCredentials = () => {
  const {
    FIREBASE_TYPE: type,
    FIREBASE_PROJECT_ID: projectId,
    FIREBASE_PRIVATE_KEY_ID: privateKeyId,
    FIREBASE_PRIVATE_KEY: privateKey,
    FIREBASE_CLIENT_EMAIL: clientEmail,
    FIREBASE_CLIENT_ID: clientId,
    FIREBASE_AUTH_URI: authUri,
    FIREBASE_TOKEN_URI: tokenUri,
    FIREBASE_AUTH_PROVIDER_CERT_URL: authProviderX509CertUrl,
    FIREBASE_CLIENT_CERT_URL: clientX509CertUrl
  } = process.env

  return {
    type,
    projectId,
    privateKeyId,
    privateKey,
    clientEmail,
    clientId,
    authUri,
    tokenUri,
    authProviderX509CertUrl,
    clientX509CertUrl
  }
}

const getDatabaseUrl = () => {
  const { projectId } = getFirebaseCredentials()
  return `https://${projectId}.firebaseio.com`
}

module.exports = () => ({
  credential: firebaseAdmin.credential.cert(getFirebaseCredentials()),
  databaseURL: getDatabaseUrl()
})

以下是我的生产应用程序的日志,使用 Zeit Now 进行部署:

08/03 08:07 AM (4m)
REQ "GET /ka/login HTTP/2.0" 69.243.47.183 -  "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:07 AM (4m)
RES "GET /ka/login HTTP/2.0" 200 3285
08/03 08:07 AM (4m)
REQ "GET /_next/01caf4c5-c7ab-4006-9f22-0e27366468c1/page/login HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:07 AM (4m)
RES "GET /_next/01caf4c5-c7ab-4006-9f22-0e27366468c1/page/login HTTP/2.0" 200 37351
08/03 08:08 AM (4m)
REQ "GET /_next/01caf4c5-c7ab-4006-9f22-0e27366468c1/page/admin HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (4m)
RES "GET /_next/01caf4c5-c7ab-4006-9f22-0e27366468c1/page/admin HTTP/2.0" 200 675
08/03 08:08 AM (4m)
REQ "POST /authWithIdToken HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (3m)
debug: Successful outgoing request. Request: { port: null,
  path: '/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com',
  host: 'www.googleapis.com',
  protocol: 'https:',
  auth: null,
  hostname: 'www.googleapis.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com',
  href: 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com',
  method: 'GET',
  headers: { host: 'www.googleapis.com' },
  body: '' } Response:  statusCode=200, expires=Thu, 03 Aug 2017 17:45:27 GMT, date=Thu, 03 Aug 2017 10:45:53 GMT, vary=X-Origin, Origin,Accept-Encoding, content-type=application/json; charset=UTF-8, x-content-type-options=nosniff, x-frame-options=SAMEORIGIN, x-xss-protection=1; mode=block, server=GSE, cache-control=public, max-age=25174, must-revalidate, no-transform, age=4937, alt-svc=quic=":443"; ma=2592000; v="39,38,37,36,35", accept-ranges=none, connection=close, , httpVersion=1.1, url=, method=null, body={
 "{{hash retracted}}": "{{certificate retracted}}",
 "{{hash retracted}}": "{{certificate retracted}}",
 "{{hash retracted}}": "{{certificate retracted}}",
 "{{hash retracted}}": "{{certificate retracted}}""
}
08/03 08:08 AM (3m)
RES "POST /authWithIdToken HTTP/2.0" 200 897
08/03 08:08 AM (2m)
REQ "GET /ka/admin HTTP/2.0" 69.243.47.183 -  "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (2m)
warn: firebase admin auth getUser auth/internal-error: uid={{uid retracted}}, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}"
08/03 08:08 AM (2m)
RES "GET /ka/admin HTTP/2.0" 302 184
08/03 08:08 AM (2m)
REQ "GET /ka/login HTTP/2.0" 69.243.47.183 -  "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (2m)
warn: firebase admin auth getUser auth/internal-error: uid={{uid retracted}}, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}"
08/03 08:08 AM (2m)
RES "GET /ka/login HTTP/2.0" 200 3285
08/03 08:08 AM (2m)
REQ "POST /authWithIdToken HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (2m)
RES "POST /authWithIdToken HTTP/2.0" 200 897
08/03 08:08 AM (2m)
warn: firebase admin auth getUser auth/internal-error: uid={{uid retracted}}, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}"
08/03 08:08 AM (2m)
REQ "POST /authWithIdToken HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (2m)
warn: firebase admin auth getUser auth/internal-error: uid={{uid retracted}}, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}"
08/03 08:08 AM (2m)
RES "POST /authWithIdToken HTTP/2.0" 200 894
08/03 08:08 AM (2m)
REQ "POST /authWithIdToken HTTP/2.0" 69.243.47.183 -  "https://georgian-chant-site-dzhuccwhhp.now.sh/ka/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
08/03 08:08 AM (2m)
RES "POST /authWithIdToken HTTP/2.0" 200 894
08/03 08:08 AM (2m)
warn: firebase admin auth getUser auth/internal-error: uid={{uid retracted}}, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}"

2017 年 8 月 15 日更新:这是使用 firebaseAdmin v5.2.0 运行时出现上述错误的堆栈跟踪(以上堆栈跟踪是针对早期版本的 firebaseAdmin)。

firebase admin auth getUser auth/internal-error: uid=RBwhJQy3ImStgNYvZICTT8M48Co1, code=auth/internal-error, message=An internal error has occurred. Raw server response: "{}", stacktrace=Error: An internal error has occurred. Raw server response: "{}"
    at FirebaseAuthError.FirebaseError [as constructor] (/myapp/node_modules/firebase-admin/lib/utils/error.js:39:28)
    at new FirebaseAuthError (/myapp/node_modules/firebase-admin/lib/utils/error.js:104:23)
    at Function.FirebaseAuthError.fromServerError (/myapp/node_modules/firebase-admin/lib/utils/error.js:128:16)
    at /myapp/node_modules/firebase-admin/lib/auth/auth-api-request.js:399:45
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

【问题讨论】:

  • 可能您的生产服务器位于阻止 SDK 连接到 ID 工具包服务器的代理或防火墙后面。你能使用像global-request-logger这样的模块来记录与后端服务器的HTTP交互,看看你得到了什么?
  • @HiranyaJayathilaka 感谢您提供有关 global-request-logger 的提示。我补充说,当应用程序启动时,日志输出只显示一个成功的传出请求,几乎可以肯定是为了初始化 firebase 管理应用程序。之后,根本没有记录更多请求(既没有成功也没有错误) - 只有我在这个问题中描述的“发生内部错误”错误。
  • 你能分享你的日志吗?我希望看到 2 个传出请求:一个用于获取 OAuth2 令牌,另一个用于 ID 工具包服务器。还向我们展示您的一些代码(尤其是您如何初始化管理应用程序)。
  • @HiranyaJayathilaka 添加了初始化代码、路由代码和日志。希望这会有所帮助。
  • 日志中捕获的 HTTP 请求来自 verifyIdToken() 调用(用于获取公钥证书)。令人费解的是为什么没有记录其他请求。由于这仅在一个环境中发生,该环境是否有可能阻止了一些传出的 HTTP 流量?另外请确认您使用的 Firebase SDK 的版本,我们可以尝试通过缩小的 JS 文件找出您的异常(如上记录)的来源。

标签: javascript firebase firebase-authentication firebase-admin


【解决方案1】:

我遇到了类似的问题。这是由传递给firebase-admin的initializeApp(...)的参数中的额外引号引起的,类似于此线程:https://github.com/firebase/firebase-admin-node/issues/137

检查你传递给initializeApp(...)的参数是否正确。

【讨论】:

    猜你喜欢
    • 2018-02-20
    • 2016-09-20
    • 2018-10-29
    • 2023-04-03
    • 2018-04-23
    • 2017-10-20
    • 2021-08-29
    • 2018-03-31
    • 1970-01-01
    相关资源
    最近更新 更多