1+ 'use strict' ;
2+ const admin = require ( 'firebase-admin' ) ;
3+ admin . initializeApp ( ) ;
4+ const express = require ( 'express' ) ;
5+ const app = express ( ) ;
6+
7+ // [START session_login]
8+ app . post ( '/sessionLogin' , ( req , res ) => {
9+ // Get the ID token passed and the CSRF token.
10+ const idToken = req . body . idToken . toString ( ) ;
11+ const csrfToken = req . body . csrfToken . toString ( ) ;
12+ // Guard against CSRF attacks.
13+ if ( csrfToken !== req . cookies . csrfToken ) {
14+ res . status ( 401 ) . send ( 'UNAUTHORIZED REQUEST!' ) ;
15+ return ;
16+ }
17+ // Set session expiration to 5 days.
18+ const expiresIn = 60 * 60 * 24 * 5 * 1000 ;
19+ // Create the session cookie. This will also verify the ID token in the process.
20+ // The session cookie will have the same claims as the ID token.
21+ // To only allow session cookie setting on recent sign-in, auth_time in ID token
22+ // can be checked to ensure user was recently signed in before creating a session cookie.
23+ admin . auth ( ) . createSessionCookie ( idToken , { expiresIn} ) . then ( ( sessionCookie ) => {
24+ // Set cookie policy for session cookie.
25+ const options = { maxAge : expiresIn , httpOnly : true , secure : true } ;
26+ res . cookie ( 'session' , sessionCookie , options ) ;
27+ res . end ( JSON . stringify ( { status : 'success' } ) ) ;
28+ } , error => {
29+ res . status ( 401 ) . send ( 'UNAUTHORIZED REQUEST!' ) ;
30+ } ) ;
31+ } ) ;
32+ // [END session_login]
33+
34+ app . post ( '/verifyToken' , ( req , res ) => {
35+ // Get the ID token.
36+ const idToken = req . body . idToken . toString ( ) ;
37+ // Set session expiration to 5 days.
38+ const expiresIn = 60 * 60 * 24 * 5 * 1000 ;
39+ // [START check_auth_time]
40+ admin . auth ( ) . verifyIdToken ( idToken ) . then ( ( decodedIdToken ) => {
41+ // Only process if the user just signed in in the last 5 minutes.
42+ if ( new Date ( ) . getTime ( ) / 1000 - decodedIdToken . auth_time < 5 * 60 ) {
43+ // Create session cookie and set it.
44+ return admin . auth ( ) . createSessionCookie ( idToken , { expiresIn} ) ;
45+ }
46+ // A user that was not recently signed in is trying to set a session cookie.
47+ // To guard against ID token theft, require re-authentication.
48+ res . status ( 401 ) . send ( 'Recent sign in required!' ) ;
49+ } ) ;
50+ // [END check_auth_time]
51+ } ) ;
52+
53+ // [START session_verify]
54+ // Whenever a user is accessing restricted content that requires authentication.
55+ app . post ( '/profile' , ( req , res ) => {
56+ const sessionCookie = req . cookies . session || '' ;
57+ // Verify the session cookie. In this case an additional check is added to detect
58+ // if the user's Firebase session was revoked, user deleted/disabled, etc.
59+ admin . auth ( ) . verifySessionCookie (
60+ sessionCookie , true /** checkRevoked */ ) . then ( ( decodedClaims ) => {
61+ serveContentForUser ( '/profile' , req , res , decodedClaims ) ;
62+ } ) . catch ( error => {
63+ // Session cookie is unavailable or invalid. Force user to login.
64+ res . redirect ( '/login' ) ;
65+ } ) ;
66+ } ) ;
67+ // [END session_verify]
68+
69+ app . post ( '/verifySessionCookie' , ( req , res ) => {
70+ const sessionCookie = req . cookies . session || '' ;
71+ // [START session_verify_with_permission_check]
72+ admin . auth ( ) . verifySessionCookie ( sessionCookie , true ) . then ( ( decodedClaims ) => {
73+ // Check custom claims to confirm user is an admin.
74+ if ( decodedClaims . admin === true ) {
75+ return serveContentForAdmin ( '/admin' , req , res , decodedClaims ) ;
76+ }
77+ res . status ( 401 ) . send ( 'UNAUTHORIZED REQUEST!' ) ;
78+ } ) . catch ( error => {
79+ // Session cookie is unavailable or invalid. Force user to login.
80+ res . redirect ( '/login' ) ;
81+ } ) ;
82+ // [END session_verify_with_permission_check]
83+ } ) ;
84+
85+
86+ // [START session_clear]
87+ app . post ( '/sessionLogout' , ( req , res ) => {
88+ res . clearCookie ( 'session' ) ;
89+ res . redirect ( '/login' ) ;
90+ } ) ;
91+ // [END session_clear]
92+
93+ // [START session_clear_and_revoke]
94+ app . post ( '/sessionLogout' , ( req , res ) => {
95+ const sessionCookie = req . cookies . session || '' ;
96+ res . clearCookie ( 'session' ) ;
97+ admin . auth ( ) . verifySessionCookie ( sessionCookie ) . then ( ( decodedClaims ) => {
98+ return admin . auth ( ) . revokeRefreshTokens ( decodedClaims . sub ) ;
99+ } ) . then ( ( ) => {
100+ res . redirect ( '/login' ) ;
101+ } ) . catch ( ( error ) => {
102+ res . redirect ( '/login' ) ;
103+ } ) ;
104+ } ) ;
105+ // [END session_clear_and_revoke]
106+
107+ function serveContentForAdmin ( ) { }
108+ function serveContentForUser ( ) { }
0 commit comments