Okay, so we've got the structure of our application for the front end in place. And we've also got a working API now. It's a very simple API built with Express. But we've got our backend working. So now let's actually set up authentication in AngularJS. And like I mentioned, we'll make use of this lock widget that Auth0 provides. So, if you come over here to auth0.com/lock, what you'll see is just a little bit of information about the lock widget.
And basically, it's a login box that is provided for us without us really needing to do any kind of coding for that login box ourselves. All we really need to do is write a little bit of configuration so that we can make it work for us. And so to get started with this, we'll actually need to use our auth provider that we brought in over here in our app.js file. So this auth provider is given to us from Auth0.
And so what we'll want to do is initialize it with init, and then pass an object that configures it. And on this object, we'll need to pass our domain. And so that's going to be our domain, which we can grab from our application settings over here. We can copy it here and just plug it right in. And then we also need our client ID. So the client ID comes from Auth0 again. That's over here and we can copy that and we can put it in as a string as well.
All right, so we've got our initialization in place for our auth provider. And what we can do now is hop over to our toolbar directive and set up some functions that will take care of logging the user in and also logging them out. And so what we'll need here are a few dependencies. We'll want the auth service that comes from Auth0. And we'll need store, which is from Angular storage.
This is going to let us work with local storage really easily. And then we'll also want location, so this is the location service that comes from AngularJS and it's going to allow us to redirect the user once they log in. Okay, so setting up our controller, we can start with our capture variable. We can do var vm equals this. And then right up top here, let's point to a couple functions that we will create.
We want a login function, so we'll say vm login is equal to a login function that will be coming next. And we want logout as well. It's going to be equal to a logout function. And then let's do this. Let's do vm auth is equal to the auth service. And what will happen here is in the functions we're about to create for logging in and logging out, we'll use this auth service to actually open the lock widget and make that request for logging in.
And then this auth service is going to hold a few properties for us that will be useful for our template. For instance, it's going to hold a property that will tell us whether or not the user is logged in and that's going to be useful for hiding and showing things. And so we put it here on our capture variable so that we can use it later in our template. All right, so we want a function for logging in and that's our login function here.
And within this login function, we need to call sign in from the auth service. So this auth service provided by Auth0 gives us this sign in method. And within sign in, the first thing that we'll pass is an empty object. And this object is where we can do some configuration for the lock widget if we want to. But we'll just leave it empty for now to get a sense for how this works first. So then we need to pass this callback. And the callback is going to have parameters for a profile and a token.
The profile is going to come back from Auth0 and it's going to be a JSON object that contains our users' profile details. So it's going to have their name and their email and their avatar URL and that sort of thing. And then the token here is going to be their JWT. It's going to be the JSON Web Token that gets returned when the user signs in. So now within this callback, let's define what we want to happen on a successful login.
So what we want to do is we want to set these items in local storage. So we can say store set. We want to set the profile and we'll pass in that profile that comes back from the call to Auth0. And likewise, we want to set our token. So we'll do store set and you can give this a name that you like. Most people do token or ID token, so maybe we'll just do ID token. And this will be the token that comes back.
And so if things are successful here, we can redirect the user to, say, the home page. So this may or may not be the way that you want to set things up in your own application, but it's just an example of what you could do. So we can say location, and we want the path to be home. So that will redirect the user to the home route in this success condition if everything checks out with that login.
Now, the third argument here is going to be another function that's going to handle any kind of error conditions. So we can say that we'll get an error back, and for now let's just log that to the console. You can choose to handle this error however you like, but for now we'll just get that message in the console. All right, and so that is our login function. It's going to make the call to sign in, which comes from the auth service provided by Auth0.
And that is then going to send a request to Auth0's servers and it's going to send the credentials that the user provides into the lock widget, which we'll see in a second. And if everything checks out it's going to set the user's profile and token within local storage. And then we're just, again, logging any possible errors to the console for now. So we've got our login function and we also need a logout function.
So logout goes here. And logging out with JSON Web Tokens really just comes down to removing those tokens from local storage. Now, something to keep in mind is that even if we remove the JWT from local storage, well it's still going to be usable as a token to access the backend for however long that token lives. So, if a token hasn't yet expired, and if somehow somebody was able to get ahold of it, it would still be usable as a token to access resources.
So one of the keys to security here is to say your token is to have kind of a short lifetime, something like an hour. And the lifetime of your token is going to really depend on your application and how secure you need to make it. If you're creating a banking application or something like that, you're going to want a really short-lived token. So this raises the question, if we have a short-lived token does that mean that the user has to sign in every hour or however long the expiry is set for?
And the answer is that by default, yes, they would have to sign in again. But what we can do to get around this is set up token refreshing, which we'll talk about a little bit more later and I'll point you to some resources to see how that works. So that's a bit of an aside, but I just wanted to put some more context and give a bit more description on how logging out with JSON Web Tokens works.
So again, here, all we really need to do to log the user out on the front end is remove their token. So we can do store remove, and we'll say that we want to remove the profile first. And then let's just copy this. And we'll say that we also want to remove the ID token. And then our auth service gives us a sign out method. And this sign out method will just kind of clear the state from the auth service.
And it'll set that property that tells us whether or not the user is authenticated back to false. So for that, we just do auth sign out. And then finally, we'll want to redirect the user to the home route again. So we'll do location and it's a path of home. All right, so now that we've got these methods in place and we've got them sitting on our capture variables here, let's make use of them over here in the template.
So we need to attach ng clicks to each of these buttons. The first one we'll do here is the login. And just for best practice, why don't we do an aria label for accessibility. And this will say login. And then let's do ng click. And this ng click is going to be pointing to that login method. And again, the capture variable is aliased to toolbar. So toolbar login. Okay, so that's for our login button.
And maybe we can just clean this up a little, just to make this look a little more presentable. So we'll come down here like this. All right, cool. And so on our logout button now, we'll attach that ng click again. So let's come up here, give it an aria label, and we'll say logout. And then ng click is going to point to toolbar logout. All right, so let's see if this works. Let's save that and we'll come over here to the browser again.
And let's check out our app. So we refresh, and if we click login now, what we see is we get the login box popping up. So again, this is great. We didn't need to provide any of our own code to make this login box work. It's nicely designed for us, and really, it's ready to go out of the box. So now what we can do is actually try signing in that user that we created earlier. But the first thing that we'll actually have to do is make a change to the settings within our application in the Auth0 dashboard.
And the change that we need to make is we need to tell it which domains should be allowed to make requests to Auth0. So right now we're testing with local host 8080. So let's copy this here and then over here in our dashboard, let's look for the allowed origins. And we'll just plug that right in. So now we can save those changes. And now if we come back over to our application we can plug in the email for the user that we created and their password.
And let's try logging in. So what we see now is that we got redirected. And now, let's actually take a look into our local storage to see what we've got. So if we come over here to local storage, what we see is we get our ID token. And that is our JSON Web Token. We've also got that object that comes through for our profile. It's got the email address, whether our email was verified or not. And it's also got things like our avatar URL.
So there we go. We have successfully logged our user in. Now, let's try the logout button here to see what happens. If we click the logout up here, everything gets removed from local storage just like we would expect. So like we touched on earlier, we don't want to have all three of these buttons showing up all the time. We want the login button to be present if the user isn't logged in.
But if they are, we want to have the profile button and the logout button. So let's do some work to actually hide and show these conditionally, given the context. So back over here in vs code, let's head over to the template once again. And what we can do is set up an ng if condition on these buttons. So on our login button, why don't we come down here and we'll say ng if. And we'll say that we want this button to be shown if the user isn't logged in.
So for that, we can use our toolbar alias and we can say auth. And then we can look at the is authenticated property. And that is authenticated property, once again, is on the auth service that Auth0 provides. And it's going to be true or false, depending on whether or not the user has a valid JSON Web Token. So then for our profile and our logout button, it's going to be kind of the same, but just the opposite.
So over here in profile, why don't we actually do the full setup? So we can come over here and give it an aria label of profile. And then right now we can actually link this using ui sreth to the profile area, so ui sreth is going to point to profile. And then we'll give it the if condition. So this time, it's going to be if the user is authenticated, then we want this button to show up. And now we can paste that ng if down here as well.
And I'll just clean this up and make it look a little bit more unified. All right, so everything should be working there. Let's head back over and check it out. So right now, we just get the login button because we don't have anything in local storage. The user is effectively not logged in. But let's see what happens if we do log in. So go login and it remembers our last user that signed in.
It kind of stores their email. So we can just click this button again. So now what we see if we've got the profile and the token in local storage. And our buttons are showing up as they should be here. We've got our profile and we can head over to our profile. Right now, we just have that hello message. And we've got our logout button. Once we click logout, we head back over to the home route, just as we'd expect.
All right, so now we've got tokens coming back to us from Auth0. We're saving them in local storage. And so now the token can be used to get access to our protected resources. We'll take a look at how to send authenticated HTTP requests in the next lecture.