firebase-functions
firebase-functions copied to clipboard
sessionClaims content not getting added to the decoded token
Related issues
N/A
[REQUIRED] Version info
node: 16.14.0
firebase-functions: 3.21.2
firebase-tools: 10.7.1
firebase-admin: 10.2.0
[REQUIRED] Test case
https://cloud.google.com/identity-platform/docs/blocking-functions#setting_custom_and_session_claims
Web App
export default function Home() {
const { data: user } = useUser();
const auth = getAuth();
function signIn() {
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider).then(async (value) => {
const idTokenResult = await value.user.getIdTokenResult(true);
console.log(idTokenResult);
});
}
if (!user) {
return <button onClick={signIn}>Sign In</button>;
}
return (
<div>
<span>{user.displayName}</span>
<button onClick={() => signOut(auth)}>Sign Out</button>
</div>
);
}
Cloud Function
export const authUserBeforeCreate = functions
.region(region)
.auth.user()
.beforeCreate((user, context) => {
// codes
});
});
export const authUserBeforeSignIn = functions
.region(region)
.auth.user()
.beforeSignIn(async (_, context) => {
return {
displayName: "Raging Tomato",
sessionClaims: { signInIpAddress: context.ipAddress },
};
});
});
[REQUIRED] Steps to reproduce
The project was originally a GCP project and is using Identity Platform but I had to setup Firebase in it for various reasons.
- Deploy a
beforeSignIn
Cloud Function viafirebase-tools
- In the web app, sign in the user using
signInWithPopup
fromfirebase/auth
- Print the
idTokenResult
export const authUserBeforeCreate = functions
.region(region)
.auth.user()
.beforeCreate((user, context) => {
// codes
});
});
export const authUserBeforeSignIn = functions
.region(region)
.auth.user()
.beforeSignIn(async (_, context) => {
return {
displayName: "Raging Tomato",
sessionClaims: { signInIpAddress: context.ipAddress },
};
});
});
[REQUIRED] Expected behavior
The sessionsClaims
I returned from the beforeSignIn
Cloud Function should be included in the decoded idToken
[REQUIRED] Actual behavior
Claims not getting added when I print the result of the codes below:
signInWithPopup(auth, provider).then(async (value) => {
const idTokenResult = await value.user.getIdTokenResult(true);
console.log(idTokenResult);
});
Were you able to successfully deploy your functions?
Yes. Also printing debug logs as expected.
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Same happening for customClaims. It doesn't work. Can we get some help?
We'll have a fix out soon (recently merged https://github.com/firebase/firebase-functions/pull/1199).
Thanks for your patience.
As far as I can tell this is still broken. displayName overwrites correclty but any returned sessionClaims and customClaims are not available on the client. Has there been any progress on this issue? Thanks for any help you can provide.
I found another bug that is possibly linked to this. I opened an issue for the same here: https://github.com/firebase/firebase-tools/issues/4946
Putting this here - just in case it solves things for anyone like me:
- Use the gcip-cloud-functions library as recommended in https://cloud.google.com/identity-platform/docs/blocking-functions?hl=en (rather than the firebase-functions approach recommended in https://firebase.google.com/docs/auth/extend-with-blocking-functions)
- If you have to stick with firebase-functions, you can still set claims through the admin api eg.
const functions = require("firebase-functions")
const admin = require("firebase-admin")
admin.initializeApp()
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
admin.auth().setCustomUserClaims(user.uid, {
admin: true
})
})
I'd recommend the using the identity platform library approach though