【问题标题】:In firebase, create a custom token with specific exp?在firebase中,创建一个具有特定exp的自定义令牌?
【发布时间】:2019-04-24 02:40:30
【问题描述】:

我注意到文档指定我可以创建一个在 3600 秒后过期的令牌 [1] 但我不知道如何使用 auth().createCustomToken ... 我可以手动使用jsonwektoken,但似乎这应该可以直接使用 firebase-admin 库进行寻址。

另一个问题是,我需要什么秘密来验证我自己以这种方式生成的令牌,uid?

index.js

// demo server generating custom auth for firebase
import Koa from 'koa'
import Koajwt from 'koa-jwt'

import Token from './token'

const app = new Koa()

// Custom 401 handling if you don't want to expose koa-jwt errors to users
app.use(function(ctx, next){
  return next().catch((err) => {
    if (401 == err.status) {
      ctx.status = 401
      ctx.body = 'Protected resource, use Authorization header to get access\n'
    } else {
      throw err
    }
  })
})

// Unprotected middleware
app.use(function(ctx, next){
    if (ctx.url.match(/^\/login/)) {
        // use router , post, https to securely send an id
        const conf = {
            uid: 'sample-user-uid',
            claims: {
              // Optional custom claims to include in the Security Rules auth / request.auth variables
              appid: 'sample-app-uid'
            }
        }
        ctx.body = {
            token: Token.generateJWT(conf)
        }
    } else {
      return next();
    }
  });

// Middleware below this line is only reached if JWT token is valid
app.use(Koajwt({ secret: 'shared-secret' }))

// Protected middleware
app.use(function(ctx){
  if (ctx.url.match(/^\/api/)) {
    ctx.body = 'protected\n'
  }
})

app.listen(3000);

token.js

//import jwt from 'jsonwebtoken'
import FirebaseAdmin from 'firebase-admin'
import serviceAccount from 'demo-admin-firebase-adminsdk-$$$$-$$$$$$.json'

export default {
    isInitialized: false,

    init() {
        FirebaseAdmin.credential.cert(serviceAccount)
        isInitialized = true
    },

    /* generateJWTprimiative (payload, signature, conf) {
        // like: jwt.sign({ data: 'foobar' }, 'secret',  { expiresIn: '15m' }) 
        jwt.sign(payload, signature, conf)
    } */

    generateJWT (conf) {
        if(! this.isInitialized)
            init()

        FirebaseAdmin.auth().createCustomToken(conf.uid, conf.claims)
        .then(token => {
            return token
        })
        .catch(err => {
            console.log('no token generate because', err)
        })
    }    
}

[1]https://firebase.google.com/docs/auth/admin/create-custom-tokens

【问题讨论】:

    标签: node.js firebase firebase-authentication


    【解决方案1】:

    您无法更改令牌过期时间。您找到的docs 包含以下文字:

    Firebase 令牌符合 OpenID Connect JWT 规范,这意味着 以下声明被保留,不能在 附加要求: ...经验...

    通过检查 Firebase Admin SDK 源代码 on GitHub 可以进一步支持这一点。

    在本节中:

    public createCustomToken(uid: string, developerClaims?: {[key: string]: any}): Promise<string> {
    
     // ....  cut for length  ....
    
      const header: JWTHeader = {
        alg: ALGORITHM_RS256,
        typ: 'JWT',
      };
      const iat = Math.floor(Date.now() / 1000);
      const body: JWTBody = {
        aud: FIREBASE_AUDIENCE,
        iat,
        exp: iat + ONE_HOUR_IN_SECONDS,
        iss: account,
        sub: account,
        uid,
      };
      if (Object.keys(claims).length > 0) {
        body.claims = claims;
      }
    
      // ....  cut for length  ....
    

    您可以看到exp 属性被硬编码为iat + ONE_HOUR_IN_SECONDS,其中常量在代码中的其他地方定义为60 * 60...

    如果您想自定义过期时间,您将不得不通过 3rd 方 JWT 包创建自己的令牌。

    对于您的第二个问题,秘密通常存储在服务器环境变量中,并且是预设的字符串或密码。 技术上可以使用 UID 作为秘密,但在安全方面这将是一个可怕的想法 - 请不要这样做。你的秘密应该像你的密码一样,保持安全,不要将它与你的源代码一起上传到 GitHub。您可以阅读有关在 Firebase in these docs here 中设置和检索环境变量的更多信息

    【讨论】:

    • 创建证书时,我必须首先提供凭据。但它实际上并不需要秘密。这让我想知道它所生成的地球是否正在使用凭证数据来保密
    • 不用太深入,看看the code for the auth section of Firebase package,看起来默认令牌生成使用了一个名为application_default_credentials.json的文件并提取了秘密(和其他安全配置数据 i>) 来自该文件。所以我猜是的,它使用凭证数据中的某些内容作为默认 Firebase 身份验证令牌的秘密。
    猜你喜欢
    • 2021-11-14
    • 2021-11-17
    • 2021-10-22
    • 2012-04-10
    • 2014-03-31
    • 2020-11-12
    • 1970-01-01
    • 2017-04-16
    • 2017-01-01
    相关资源
    最近更新 更多