In firebase, create a custom token with specific exp?












0















I notice that the docs specify that I can create a token to expire up to 3600 seconds later[1] But I don't see how to do that with auth().createCustomToken ... I can manually do it with jsonwektoken, but it seems like this should be addressable directly with firebase-admin library.



Another question is, what is the secret I need to verify my own token generated in this way, the 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 accessn'
} 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 = 'protectedn'
}
})

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










share|improve this question



























    0















    I notice that the docs specify that I can create a token to expire up to 3600 seconds later[1] But I don't see how to do that with auth().createCustomToken ... I can manually do it with jsonwektoken, but it seems like this should be addressable directly with firebase-admin library.



    Another question is, what is the secret I need to verify my own token generated in this way, the 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 accessn'
    } 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 = 'protectedn'
    }
    })

    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










    share|improve this question

























      0












      0








      0








      I notice that the docs specify that I can create a token to expire up to 3600 seconds later[1] But I don't see how to do that with auth().createCustomToken ... I can manually do it with jsonwektoken, but it seems like this should be addressable directly with firebase-admin library.



      Another question is, what is the secret I need to verify my own token generated in this way, the 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 accessn'
      } 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 = 'protectedn'
      }
      })

      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










      share|improve this question














      I notice that the docs specify that I can create a token to expire up to 3600 seconds later[1] But I don't see how to do that with auth().createCustomToken ... I can manually do it with jsonwektoken, but it seems like this should be addressable directly with firebase-admin library.



      Another question is, what is the secret I need to verify my own token generated in this way, the 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 accessn'
      } 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 = 'protectedn'
      }
      })

      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 '18 at 13:50









      roberto tomásroberto tomás

      1,71122137




      1,71122137
























          1 Answer
          1






          active

          oldest

          votes


















          1














          You can't change the token expiration. The docs you found includes the words:




          Firebase tokens comply with the OpenID Connect JWT spec, which means
          the following claims are reserved and cannot be specified within the
          additional claims:
          ... exp ...




          This is further backed up by inspecting the Firebase Admin SDK source code on GitHub.



          In this section:



          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 ....


          You can see the exp property is hard coded to be iat + ONE_HOUR_IN_SECONDS where the constant is defined elsewhere in the code as 60 * 60...



          If you want to customize the expiration time, you will HAVE to create your own token via a 3rd party JWT package.



          To your 2nd question, a secret is typically stored in the server environment variables, and is a pre-set string or password. Technically you could use the UID as the secret, but that would be a TERRIBLE idea security wise - please don't do this. Your secret should be like your password, keep it secure and don't upload it with your source code to GitHub. You can read more about setting and retrieving environment variables in Firebase in these docs here






          share|improve this answer
























          • When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

            – roberto tomás
            Nov 22 '18 at 18:06






          • 1





            Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

            – JeremyW
            Nov 26 '18 at 13:13













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413573%2fin-firebase-create-a-custom-token-with-specific-exp%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          You can't change the token expiration. The docs you found includes the words:




          Firebase tokens comply with the OpenID Connect JWT spec, which means
          the following claims are reserved and cannot be specified within the
          additional claims:
          ... exp ...




          This is further backed up by inspecting the Firebase Admin SDK source code on GitHub.



          In this section:



          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 ....


          You can see the exp property is hard coded to be iat + ONE_HOUR_IN_SECONDS where the constant is defined elsewhere in the code as 60 * 60...



          If you want to customize the expiration time, you will HAVE to create your own token via a 3rd party JWT package.



          To your 2nd question, a secret is typically stored in the server environment variables, and is a pre-set string or password. Technically you could use the UID as the secret, but that would be a TERRIBLE idea security wise - please don't do this. Your secret should be like your password, keep it secure and don't upload it with your source code to GitHub. You can read more about setting and retrieving environment variables in Firebase in these docs here






          share|improve this answer
























          • When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

            – roberto tomás
            Nov 22 '18 at 18:06






          • 1





            Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

            – JeremyW
            Nov 26 '18 at 13:13


















          1














          You can't change the token expiration. The docs you found includes the words:




          Firebase tokens comply with the OpenID Connect JWT spec, which means
          the following claims are reserved and cannot be specified within the
          additional claims:
          ... exp ...




          This is further backed up by inspecting the Firebase Admin SDK source code on GitHub.



          In this section:



          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 ....


          You can see the exp property is hard coded to be iat + ONE_HOUR_IN_SECONDS where the constant is defined elsewhere in the code as 60 * 60...



          If you want to customize the expiration time, you will HAVE to create your own token via a 3rd party JWT package.



          To your 2nd question, a secret is typically stored in the server environment variables, and is a pre-set string or password. Technically you could use the UID as the secret, but that would be a TERRIBLE idea security wise - please don't do this. Your secret should be like your password, keep it secure and don't upload it with your source code to GitHub. You can read more about setting and retrieving environment variables in Firebase in these docs here






          share|improve this answer
























          • When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

            – roberto tomás
            Nov 22 '18 at 18:06






          • 1





            Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

            – JeremyW
            Nov 26 '18 at 13:13
















          1












          1








          1







          You can't change the token expiration. The docs you found includes the words:




          Firebase tokens comply with the OpenID Connect JWT spec, which means
          the following claims are reserved and cannot be specified within the
          additional claims:
          ... exp ...




          This is further backed up by inspecting the Firebase Admin SDK source code on GitHub.



          In this section:



          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 ....


          You can see the exp property is hard coded to be iat + ONE_HOUR_IN_SECONDS where the constant is defined elsewhere in the code as 60 * 60...



          If you want to customize the expiration time, you will HAVE to create your own token via a 3rd party JWT package.



          To your 2nd question, a secret is typically stored in the server environment variables, and is a pre-set string or password. Technically you could use the UID as the secret, but that would be a TERRIBLE idea security wise - please don't do this. Your secret should be like your password, keep it secure and don't upload it with your source code to GitHub. You can read more about setting and retrieving environment variables in Firebase in these docs here






          share|improve this answer













          You can't change the token expiration. The docs you found includes the words:




          Firebase tokens comply with the OpenID Connect JWT spec, which means
          the following claims are reserved and cannot be specified within the
          additional claims:
          ... exp ...




          This is further backed up by inspecting the Firebase Admin SDK source code on GitHub.



          In this section:



          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 ....


          You can see the exp property is hard coded to be iat + ONE_HOUR_IN_SECONDS where the constant is defined elsewhere in the code as 60 * 60...



          If you want to customize the expiration time, you will HAVE to create your own token via a 3rd party JWT package.



          To your 2nd question, a secret is typically stored in the server environment variables, and is a pre-set string or password. Technically you could use the UID as the secret, but that would be a TERRIBLE idea security wise - please don't do this. Your secret should be like your password, keep it secure and don't upload it with your source code to GitHub. You can read more about setting and retrieving environment variables in Firebase in these docs here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '18 at 17:43









          JeremyWJeremyW

          1,983515




          1,983515













          • When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

            – roberto tomás
            Nov 22 '18 at 18:06






          • 1





            Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

            – JeremyW
            Nov 26 '18 at 13:13





















          • When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

            – roberto tomás
            Nov 22 '18 at 18:06






          • 1





            Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

            – JeremyW
            Nov 26 '18 at 13:13



















          When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

          – roberto tomás
          Nov 22 '18 at 18:06





          When I created the cert, I have to first provide credentials. But at no point does it actually requires a secret. That makes me wonder if this earth that it’s generating is using the credential data for the secret

          – roberto tomás
          Nov 22 '18 at 18:06




          1




          1





          Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

          – JeremyW
          Nov 26 '18 at 13:13







          Without getting too deep into it, looking at the code for the auth section of Firebase package it looks like the default token generation uses a file named application_default_credentials.json and pulls out the secret (and other secure config data) from that file. So I'm guessing that yeah, it uses something in the credential data as the secret for the default Firebase auth token.

          – JeremyW
          Nov 26 '18 at 13:13






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413573%2fin-firebase-create-a-custom-token-with-specific-exp%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

          ComboBox Display Member on multiple fields

          Is it possible to collect Nectar points via Trainline?