admin管理员组

文章数量:1324837

How can I set session expiration for a Firebase auth session? By default the session never expires.

I wish for the session to expire after 8 hours of inactivity.

I have read the documentation but cannot figure out how to set session expiration.

My code for signing in the user and performing tasks on sign in and sign out

firebase.auth().signInWithEmailAndPassword(data.email, data.password)

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    //Signed in
  }else{
    //Signed out
  }
}

Thanks for all replies! I have tried but cannot seem to get Firebase-admin to work.

Firebase-db.js

const admin = require('firebase-admin')

const databaseConnection = {
  serviceAccountFile: './serviceAccount.json',
  databaseURL: '/'
}

const serviceAccount = require(databaseConnection.serviceAccountFile)

const app = admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: databaseConnection.databaseURL
}, 'test')

const database = admin.database(app)

module.exports = database

sessionSignout.js

const functions = require('firebase-functions')   
const database = require('../../firebase-db')
const admin = database.admin

exports.sessionSignout = functions
.region('europe-west1')
.pubsub
.schedule('*/15 * * * *')
.timeZone('Europe/Stockholm')
.onRun(async (event) => {
  database.ref(`users`)
  .once('value', (usersSnapshots) => {
    usersSnapshots.forEach((snapshot) => {
      const uid = snapshot.key
      admin.auth().revokeRefreshTokens(uid)
    })
  })
}

I get error

Error: function execution failed. Details: Cannot read property 'auth' of undefined

How can I set session expiration for a Firebase auth session? By default the session never expires.

I wish for the session to expire after 8 hours of inactivity.

I have read the documentation but cannot figure out how to set session expiration.

My code for signing in the user and performing tasks on sign in and sign out

firebase.auth().signInWithEmailAndPassword(data.email, data.password)

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    //Signed in
  }else{
    //Signed out
  }
}

Thanks for all replies! I have tried but cannot seem to get Firebase-admin to work.

Firebase-db.js

const admin = require('firebase-admin')

const databaseConnection = {
  serviceAccountFile: './serviceAccount.json',
  databaseURL: 'https://myProject.firebaseio./'
}

const serviceAccount = require(databaseConnection.serviceAccountFile)

const app = admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: databaseConnection.databaseURL
}, 'test')

const database = admin.database(app)

module.exports = database

sessionSignout.js

const functions = require('firebase-functions')   
const database = require('../../firebase-db')
const admin = database.admin

exports.sessionSignout = functions
.region('europe-west1')
.pubsub
.schedule('*/15 * * * *')
.timeZone('Europe/Stockholm')
.onRun(async (event) => {
  database.ref(`users`)
  .once('value', (usersSnapshots) => {
    usersSnapshots.forEach((snapshot) => {
      const uid = snapshot.key
      admin.auth().revokeRefreshTokens(uid)
    })
  })
}

I get error

Error: function execution failed. Details: Cannot read property 'auth' of undefined

Share Improve this question edited Oct 13, 2019 at 17:15 Kermit asked Oct 12, 2019 at 15:54 KermitKermit 3,4176 gold badges36 silver badges61 bronze badges 5
  • use custom auth claim and only allow a user to access data if it has the timestamp in last 8 hours. else don't allow access. it is somewhat session expiry ;) – Harkal Commented Oct 12, 2019 at 16:03
  • 1 or just simply revoke the session token using admin sdk. the link you have mentioned have the sample implementation – Harkal Commented Oct 12, 2019 at 16:07
  • Hi Har Kal! Thank you for the reply! I will give it a try! Many thanks! – Kermit Commented Oct 13, 2019 at 8:23
  • I found the error, see my plete code below. /K – Kermit Commented Oct 13, 2019 at 21:35
  • change "const admin = database.admin" on line 3rd to "import * as admin from 'firebase-admin'" – Harkal Commented Oct 14, 2019 at 9:38
Add a ment  | 

2 Answers 2

Reset to default 5

The documentation you linked says that you can use the Firebase Admin SDK to revoke a user's refresh tokens in order to terminate their session. This code must run on a backend you control, which means that you won't be able to do it in the client app. The backend will need to know when the user became "inactive", by whatever definition of that you choose. Wiring this all up is non-trivial, but possible.

Thanks for all the answers! I just wanted to share my code for others to use.

I already had code in place to acmodate presence awareness.

index.js

import database from './firebase/firebase' //Firebase setup for client

firebase.auth().onAuthStateChanged((user) => {
  //Handle login and redirect

  if (user) {
    //We are logged in
    addPresenceAwarenessListener()
  }else{
    ...
  }
}

const addPresenceAwarenessListener = () => {
  // Create a reference to the special '.info/connected' path in 
  // Realtime Database. This path returns `true` when connected
  // and `false` when disconnected.
  database.ref('.info/connected').on('value', (snapshot) => {
    // If we're not currently connected, don't do anything.
    if (snapshot.val() == false) {
      return
    }

    const uid = firebase.auth().currentUser.uid

    //Push last login/logout to user profile
    const userLastLoginOutRef = database.ref(`users/${uid}`)
    userLastLoginOutRef.onDisconnect().update({lastLoginOut: firebase.database.ServerValue.TIMESTAMP})
    .then(() => { userLastLoginOutRef.update({lastLoginOut: firebase.database.ServerValue.TIMESTAMP}) })
  })
}

Session handling - expire sessions after n hours (setting "sessExp" in database)

firebase-db.js - Basic Firebase setup for cloud functions

const admin = require('firebase-admin')

const databaseConnection = {
  serviceAccountFile: './my-project.json',
  databaseURL: 'https://my-project.firebaseio./'
}

const serviceAccount = require(databaseConnection.serviceAccountFile)

const app = admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: databaseConnection.databaseURL
}, 'remindMiNotifier')

const database = admin.database(app)
module.exports = database

sessionSignout.js - Signout user after a specific time period - if specified. Default to eternal session.

const functions = require('firebase-functions')
const moment = require('moment')
const database = require('../../firebase-db')
const admin = database.app

//Import enviroment variable config (.env)
require('dotenv').config()

//Export cron job - deploy: firebase deploy --only functions:sessionSignout
exports.sessionSignout = functions
.region('europe-west1')
.pubsub
.schedule('*/15 * * * *')
.timeZone('Europe/Stockholm')
.onRun(async (event) => {
  //Start execution
  const now = moment()
  const defaultSessionTime = 0 //Eternal session

  //Get all users and calculate inactive time - time since last login
  let logoutUsersArray = []
  await database.ref(`users`)
  .once('value', (usersSnapshots) => {
    usersSnapshots.forEach((snapshot) => {
      const userData = snapshot.val()
      const lastLoginOut = (userData.lastLoginOut) ? userData.lastLoginOut : 0
      //Only process users that has a login/out time stamp
      if(lastLoginOut > 0){
        const userSessionTime = (userData.sessExp) ? userData.sessExp : defaultSessionTime
        const hoursSinceLastLoginOut = now.diff(lastLoginOut, 'hours')
        const logoutUser = ( userSessionTime > 0 && (hoursSinceLastLoginOut > userSessionTime) )

        if(logoutUser){
          const userId = snapshot.key
          const userName = (userData.alias) ? userData.alias : userData.displayName
          const email = (userData.email) ? userData.email : ''
          const userObject = {
            userId,
            userName,
            email,
            lastLoginOut,
            diffHours: now.diff(lastLoginOut, 'hours')
          }
          logoutUsersArray.push(userObject)
        }
      }
    })
  })
  console.log('logoutUsersArray', logoutUsersArray)

  //Collect all promises to carry out 
  let myPromises = []

  // Revoke all refresh tokens for each user
  logoutUsersArray.forEach((logoutUser) => {
    const uid = logoutUser.userId
    myPromises.push(
      admin.auth().revokeRefreshTokens(uid)
      .then(() => {
        return admin.auth().getUser(uid)
      })
      .then((userRecord) => {
        return new Date(userRecord.tokensValidAfterTime).getTime() / 1000
      })
      .then((timestamp) => {
        // Retrieve the timestamp of the revocation, in seconds since the epoch.
        console.log('Tokens revoked at: ', timestamp)
        return Promise.resolve(true)
      })
      .catch((err) => {
        console.error('Error', err)
        return Promise.reject(err)
      })
    )
  })

  //Execute promises
  console.log('Execute promises')
  return Promise.all(myPromises)
  .then(() => Promise.resolve(true))
  .catch((err) => {
    console.error('Error', err)
    return Promise.reject(err)
  })

})//End sessionSignout

Documentation on firebase-admin can be found here.

本文标签: javascriptFirebase AuthSet session expirationStack Overflow