在firebase中,创建具有特定exp的自定义令牌吗?

时间:2018-11-21 13:50:55

标签: node.js firebase firebase-authentication

我注意到文档指定我可以创建一个令牌,该令牌可以在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

1 个答案:

答案 0 :(得分:1)

您不能更改令牌的到期时间。您发现的docs包含以下单词:

  

Firebase令牌符合OpenID Connect JWT规范,这意味着   以下权利要求是保留的,不能在以下范围内指定   附加声明:   ... exp ...

可通过检查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 ...

如果您要自定义到期时间,则必须通过第三方JWT包创建自己的令牌。

对于第二个问题,机密通常存储在服务器环境变量中,并且是预设的字符串或密码。 从技术上说,您可以将UID用作机密,但这在安全性方面是一个可怕的主意-请不要这样做。您的秘密应该像您的密码一样,保持安全,并且不要与您的源代码一起将其上传到GitHub。您可以在Firebase in these docs here

中了解有关设置和检索环境变量的更多信息。