Angular, Node, and Auth0

February 20, 2018

I needed authentication for my Angular app (which has a Node.js backend) on a recent project, and so I started looking at options and decided to use Auth0. There are a lot of options, including using passport-local and doing authentication on your own. But to avoid managing users and security all on my own, I decided to use Auth0's service.

To get started, I used this article from Auth0's blog to implement authentication in my app. I won't put everything from that article into this blog post, but the basic ideas are as follows:

  1. Implement an AuthService in your app that handles the login status and originating the authenticate action.
  2. That same auth service receives the token back from Auth0 in a callback route and saves it in localStorage for use when calling your server.
  3. On every call to the server, that token is placed in the header to be verified on the server.
  4. On the server, verify the token. If it is valid, continue on with the request. If not, return an error.
  5. Implement an AuthGuard in the Angular app to prevent access to parts of the app that require login.

When you're finished with part 1 of the article (I didn't even do part 2, because it covered things I didn't need) you should have your application secured to only being available to those who are authenticated. This part didn't take too long, maybe a couple hours for implementation. It was really nice and really quick.

The next part of really integrating your application with Auth0, though, is providing the ability for your user to update their information. They don't really have a way to do that very easily (or at all, possibly) right through Auth0. So what I hope to cover here is how you can allow your users to update their account information through your application.

The easiest part of all of this is deciding which fields you want your users to be able to change. In my case, it was pretty simple up front: first name, last name, and email address. You really can provide whatever you would like, though. Build a form in your Angular app however you like, get the information, and post it to the server. That's where the real work begins.

By default, you don't get to automatically update a user, or even get their profile information, even when you set up your client in Auth0. To do this, you have to use their Management API. To use it, you need to get a token before making calls to the Management API. This requires a second client to be made. So I made a non-interactive client in Auth0's dashboard, and got the client_id, client_secret, and audience from the settings page for the client. The audience is a URL, like https://username.auth0.com/api/v2. I used a Sails.js server, but it's just a node server so making the request in the following way is the same for all node servers. I used the request-promise package:

getApiToken: async function() {
	const token = await request({
		uri: sails.config.auth.managementApi.tokenEndpoint,
		body: {
			client_id: sails.config.auth.managementApi.clientId,
			client_secret: sails.config.auth.managementApi.clientSecret,
			audience: sails.config.auth.managementApi.audience,
			grant_type: 'client_credentials',
		},
		method: 'POST',
		json: true,
	});

	return token;
}
		

This function is pretty simple: It makes a POST request to Auth0, and the return value is the token needed to access the API. After you get the token, you can then get the users's profile, update the user's profile, or any of the other functions available in the Management API. Here's an example of getting the user's profile:

getUserProfile: async function(userId, token) {
	const userProfile = await request({
		uri: `https://username.auth0.com/api/v2/users/${userId}`,
		method: 'GET',
		headers: { authorization: `Bearer ${token.access_token}`, 'content-type': 'application/json' },
		json: true,
	});

	return userProfile;
}
		

This is another pretty simple function: make a GET request to the Management API with a user id (which comes after verifying the token passed from the front end), and the token obtained in the last step.

Updating is the same idea; make a PATCH request to the same URL as listed in the getUserProfile function, and then let the management API do its work. There are many available functions on the API; the user functions are listed here.

Something to keep in mind is that a lot of the fields you may want to udpate need to be saved in the user_metadata field. For example, in my application, the first and last name fields are saved in the user_metadata attribute. If the field isn't listed on the first level of the JSON object here or here, put the fields in the user_metadata field. Also when updating user_metadata, make sure that the sub attributes are always spelled the same. The user_metadata attribute is merged together on each update, so if you had firstName one time, and firstNAme a different time, the user_metadata object would have both of those attributes.

Another thing that I made sure to do is to check what source the user account was created with; like if it was a social media login or a Username-Password combination. The Username-Password combination means the user created an account on Auth0's site to log in to your application. I only allow them to change their email address if they used that method to sign up for the application. There may be a way to change the email still if they signed up with, say, Google, but I didn't want to go through the steps to verify they were updating things correctly. Also, my app won't have social login capability.

Hopefully this all helped you implement Auth0 more fully in your application. It took me a little bit to figure out the steps to implementing this in my application, and I hope it saves you time!