
Using Netlify Identity in a production application
What is Netlify Identity
Netlify Identity is a new subservice that Netlify has recently released. It fulfills a similar role to other services such as Auth0. Netlify Identity and Auth0 fall into the category known as Identity as a Service (IDaaS for short). The key benefit we see in Netlify Identity over Auth0 is it's integration with other Netlify services like Functions (AWS Lambda functions deployed via Netlify).
How do I use it?
Netlify has great documentation on how to enable Identity with an existing site. If you're unfamiliar with any of the Netlify suite you can checkout this tutorial on how to get started from scratch.
What can it do?
There's a few things that we found incredibly useful for our implementation.
Custom User Validation
In combination with Functions it is possible to validate enrollments using custom functions. This is done using an "event". Identity events are triggered for validation, signup and login. This is particularly useful when migrating an existing userbase to Netlify as you can use this custom validation event to do things like check if the email has already been enrolled in your external identity provider. Here's an example of how you might reject signups with emails that already exist externally:
// lambda/identity-signup.js
// use browser fetch in node (node module)
const fetch = require('node-fetch');
// function which returns a promise which resolves
// to a boolean depending on whether the user exists
const EXTERNAL_USERBASE = 'https://example.com/api/v1/user';
const userExists = (email) => {
return (
fetch(EXTERNAL_USERBASE)
.then(response => response.json())
.then(data => !!data)
)
}
// exports.handler function will be called when
// a request hits this lambda function URL
exports.handler = function (event, context) {
const { user, event: eventName } = JSON.parse(event.body);
if (eventName !== 'signup')
return { statusCode: 200, body: '' };
return (
userExists(email)
.then(exists => {
if (exists) {
// A statusCode other than 200 or 204 will stop signup
return { statusCode: 400, body: 'User exists!' };
}
else
{
// Our user doesn't exist!
return { statusCode: 200, body: JSON.stringify({
user_metadata: {
custom_data: 'This is useful to store things like a user ID from a previous identity service'
}
}) };
}
})
)
}
Ability to create accounts programmatically
Any Netlify Function has the ability to create Identity accounts programatically by hitting the admin endpoint (SITE_URL/.netlify/indentity/admin/users
).
// lambda/create-user.js
// use browser fetch in node (node module)
const fetch = require('node-fetch');
exports.handler = (event, context) => {
if (event.httpMethod !== 'POST')
return { statusCode: 400, body: 'HTTP Method Unavailable' };
// send account information along with the POST
const { email, password, full_name } = JSON.parse(event.body);
// identity.token is a short lived admin token which
// is provided to all Netlify Functions to interact
// with the Identity API
const { identity } = context.clientContext;
return (
fetch(`${identity.url}/admin/users`, {
method: 'POST',
headers: { Authorization: `Bearer ${identity.token}` },
body: JSON.stringify({
email,
password,
confirm: true,
user_metadata: {
full_name,
}
})
})
);
}
Pull Request Environments
Netlify also supports independent Functions in each pull request which gives you the power of testing your API integration in a pull request before going live. There's ways to do this with other cloud function services but the granularity of per pull request deploys is hard to beat. With other services you're usually working with a select number of "development" or "staging" environments which you have to manually configure with the changes you'd like to test.
When do I start using it?
Netlify Identity is ready to be used in your production environment today. It's relatively simple to move away from maintaining your own identity system and switching it for Netlify. Most if not all of the functionality you already have is supported in their GoTrue API.