Kent C. Dodds: OK, so now here we have our application. Let's just make sure it's all working here. We can login, we can logout, we can get users whether or not we are logged in. This is what we are trying to protect. If we look in our local storage here, because I logged out there's nothing in here, but if I login again it is in here. I logout, it goes away. If I'm logged in and I say get user, then I'm sending the authorization header with the token that the server gave to me in this login request.
Now what we need to do is set up the server so that it will take this authorization header into account when this get user endpoint is hit. This is actually very simple with a module that we have called express jot. We'll go ahead and install that npm install Express Jot, and then up here we'll simply require express jot, and then it's as simple as an app.use Express Jot. This will take a secret, and we'll use the same jot secret.
Because this is going to be verifying our tokens, we need to verify it with the same secret. That's actually everything that we need to do. However, when a user is logging in, they obviously won't have a token, and so we need to add unless, on this middleware, and we'll say the path is in this array/login. Now Express Jot, under the covers, is going to intercept all of the requests that come in.
It will take this authorization header, with the bearer and the token, it will decode that token using the jot secret. If it does decode properly, and the signature is verified, then it will add user to the request object, and the user property will simply be the decoded json object. We're going to see what that looks like here in a moment, but let's go ahead and see what breaks here.
I'm pointing to the server directly, to the random user endpoint, and if I refresh here, now I'm getting an unauthorized error, "No authorization header was found." If I refresh here, I'm not logged in, I say get...Oh, except I think that I am logged in. Refresh here, OK, "No authorization header was found," and the air is coming from this Express Jot.
With just these two lines, we were able to take our application and add Express Jot. Obviously we do have this jot signing, so that's a couple of extra lines, but it's actually very simple to add this authentication scheme to a node application. We do have a couple of more things that we want to do on the front end to make things a little more sensible. If I go ahead and login here, I login. N
Now I have, in our resources, I have that auth token. We'll clear our network here, say get user, and I can get the user. We can see on here I have the authorization header, so that's why I was able to get through. If I refresh the page, you'll see it's not showing that I'm logged in, but when I get the user everything works out fine, because I do have that token locally in the client.
What we want to implement now is to be automatically logged in when we refresh the page if we have the token locally. Let's go to our app, and we'll have this initialization step in our controller, and we'll say, "user factory.getuser" then we'll say vmuser is equal to the data that comes back, and so let's go to our user factory, and will add a getuser function here, and we'll define that down here. We'll simply say if auth token factory get token, so if there is a token in existence, then we can return $HTTP.getapiurl/me.
Otherwise we'll return $Q.reject, with the data client has no auth token. We'll need to inject Q here. Now we need to implement this /me endpoint. We'll go back to our server and just right here we'll say app.get/me. Because we have this Express Jot here, and the only path that is being excluded is the /login, we can know that this /me is being protected by this Express Jot, so no request will come through to /me unless they pass through this Express Jot first.
We can rely on the fact that the user is authenticated at this point, and Express Jot will put the decoded token onto the user object, and so I can simply just say "response send rec.user." This is very simple, so all of this should work, assuming I didn't break anything. Let's just double check in our resources. We have the auth token, now if I refresh...There we go, Kent C Dodds, we're automatically logged in, and we can get the users right from the get go.
If we logout, there's no token in here. Oops. We'll refresh, and now we're not able to get any users, and so that's the basic gist of what we're trying to accomplish in the series. Actually, there's one other thing that we want to do, and that's just for the fun of it. Well say ng show, or actually we'll say a hide when there's a vm user we'll hide this, and ng show when there is a vm user. Now let's refresh.
Now it makes more sense. Get random user. We'll login, and we'll login with the wrong password, password/username incorrect. We login without a password...OK, so all of our error handling is working. Now we login, here we have...and now we can get the user, and we can logout, and go back and forth that way. If we just hit the endpoint directly, "No authorization header found," and so this application is a working application, and that is what we've created using Jots.
Let's just take this full circle and explain what's happening here. We'll refresh the page here, we'll clear out here. We login with kentcdodds, and P as our password. We send that with this login request. Let's make this big here. The payload is the password and username. Then the server returns us a signed token with a secret that only the server knows about, and the user.
Then behind the scenes on the client we add an auth token to local storage, and that we have an auth interceptor that will intercept every request that we make with HTTP, and add this auth token to our request. If we look at our network tab here again, say "get user," we get the user, and here in our headers we have that authorization header with the bearer and the token. Then when we want to logout, let's take a look at our resources here.
We say logout, and that auth token is removed from local storage, and the user on the view model is set to null, and so our view updates as well. That's the application, that's Jots with Angular.