Hi @Malcolm,
- User IDs are generated when a user signs-up or is invited and stay persistent through any kind of change except user deletion. It’s also unique to each user (at least in each Identity instance), so you can safely use it to identify each user individually. To access the user ID in a function, well it’s kinda tricky. I say tricky because the way Netlify Identity works with Netlify Functions is that, the function needs an Authorisation header with a Bearer token sent with the fetch request. The Bearer token is basically the JWT token generated for the user which, if you’re using Netlify Identity Widget, can be accessed using
netlifyIdentity.currentUser().token.access_token
. So the overall fetch call could look something like:
fetch('/.netify/functions/<function-name>/', {
headers: {
Authorization: `Bearer ${netlifyIdentity.currentUser().token.access_token}`
}
})
Once the function is called this way, you get the user in the function, like:
exports.handler = async (event, context) => {
console.log(context.clientContext.user.sub)
}
The downside is, as you might have guessed, you can only get this ID when you’re logged in as that particular user as the ID will depend on what Bearer token is being sent. In most cases, this is what you need. A user should only be able to access/edit their data when they’re logged in as themselves, but you can’t run any admin actions (example thread here). If you want to run some admin-side actions, there’s a workaround mentioned in that thread towards the end, but here’s it in short: When a user signs-up, it’s recommended to get the user ID then and there and save it to an external database or something using the identity-signup
function. So, in future, you could find the user by ID.
1b) Yes, the ID is encoded within the token. Basically, all of the data that you’d find in the user
object in the function, is just the decoded JWT. Yes, the ID can be accessed on the client side, actually the entire Identity data of the logged in user can be accessed by anyone on the client side, but they can’t do much with it if you’ve set your security in the function correctly. For example, if you are not using any JS bundler and directly importing the Identity Widget from the CDN, it allows anyone to access netlifyIdentity
in the global scope. So, once logged in, they can do something like netlifyIdentity.currentUser()
to get their own data, but they definitely can’t get someone else’s data with this. However, if they get their Bearer token, then can call your serverless function with it and act maliciously. So, for any kind of secure (admin-only) functions, I’d advise you to add a condition that will allow access to the function only when you call it. For example, something like this:
exports.handler = async (event, context) => {
const user = context.clientContext.user
if (user && user.sub === 'your-admin-user-id') {
// process the function
} else {
return: {
statusCode: 401
body: JSON.stringify('Unauthorised')
}
}
}
- I think, the answer for this question is up to you. You’d have to figure out the most optimal way fo your use case and keeping in mind the limitations of your frontend and backend systems. Yes, you can keep a database entry unique to each user by their ID, but you’d have to see if it scales correctly if you need it.