diff --git a/lessons/full-stack-build-an-app-adding-support-for-login/index.md b/lessons/full-stack-build-an-app-adding-support-for-login/index.md index 0fde68be..6f30c10a 100644 --- a/lessons/full-stack-build-an-app-adding-support-for-login/index.md +++ b/lessons/full-stack-build-an-app-adding-support-for-login/index.md @@ -16,7 +16,7 @@ and include that with every request. We want to handle the user's unencrypted password as little as possible. To do this, the client and the server communicate with a system known as JavaScript Web Tokens or JWTs. (some pronounce this as Jay-Double-U-Tees and others as `joots` to rhyme with -`scoots`) +`scoots`). The idea of a JWT is an encoded and cryptographically **signed** bit of data that the server can hand back to the client, which means "If you hand me back @@ -38,7 +38,7 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjEiLCJGdWxsTmFtZSI6IkdhdmluIFN0YXJ Pretty indecipherable, right? Fortunately, JWTs are easily decoded by our computers. The website `jwt.io` has a decoder on the home page. Try copying the -above text and pasting it into their _Debugger_ +above text and pasting it into their _Debugger_. What you will see is this: @@ -60,7 +60,7 @@ properly decode the rest of the token. Next comes the `payload`. The payload is the part we, as developers, specify data. Each of these data elements is considered a`claim`. The first _three_ -claims here, `Id`, `FullName`, and `Email` were generated by code (which we are +claims here, `Id`, `FullName`, and `Email`, were generated by code (which we are about to write) and represent a logged-in user's details. The next three represent details about the token itself. `nbf` is a claim that stands for `Not Before`, meaning that the token is not valid for any time _earlier_ than @@ -72,7 +72,7 @@ The final section is the _signature_ of the token. It uses cryptographic functions to add data to the token using a server's _secret key_. This data represents a _hash_ of the other parts of the token. If anyone were to change even a single character of the other parts of the message, say changing the `Id` -from `1` to `2` they would **not** be able to resign that message with valid +from `1` to `2`, they would **not** be able to resign that message with valid data. They lack the server's secret key. The data is decodable by anyone, but only the server itself can change/update the data. Thus it is essential not to put **secret** information in the payload since JWT tokens are not @@ -85,7 +85,7 @@ do this by specifying a unique `header` value that includes this token. ## Adding a controller to manage "sessions." -Thinking again about _resources_ we will consider the user logging in to be the +Thinking again about _resources_, we will consider the user logging in to be the _CREATION_ of a _Session_. While we won't record creating a session in our database, though we could, we still think of this as its own resource with a `POST` create action. @@ -104,8 +104,8 @@ using TacoTuesday.Utils; namespace TacoTuesday.Controllers { // All of these routes will be at the base URL: /api/Sessions - // That is what "api/[controller]" means below. It uses the name of the controller - // in this case RestaurantsController to determine the URL + // That is what "api/[controller]" means below. It uses the name of the controller, + // in this case, RestaurantsController, to determine the URL [Route("api/[controller]")] [ApiController] public class SessionsController : ControllerBase @@ -161,10 +161,10 @@ dotnet user-secrets init ``` User secret initialization creates a file outside our project to store secret -information. This way the data is not stored in our repository for others to +information. This way, the data is not stored in our repository for others to see. -Next, you told the secrets to store `JWT_KEY` +Next, you told the secrets to store `JWT_KEY`. ```shell dotnet user-secrets set "JWT_KEY" "Long set of Random Letters and Numbers like iExEUNxxv9zylIuT2VMrsMsQEKjjKs1XrYFntsafKgQs90HndTX0yw8xLhFHk9O" @@ -173,8 +173,8 @@ dotnet user-secrets set "JWT_KEY" "Long set of Random Letters and Numbers like i The `JWT_KEY` should be a relatively long set of random characters. These random characters are considered _high entropy_ implying that it will be tough for someone to guess this secret. An excellent website to generate these kinds of -secrets is: -[Gibson Research Corporation's Password Page](https://www.grc.com/passwords.htm) +secrets is +[Gibson Research Corporation's, Password Page](https://www.grc.com/passwords.htm). > NOTE: If you are going to deploy this with Heroku, you'll need to run > `heroku config:set JWT_KEY="xxxx"` with your specific key in place of `xxxx` @@ -194,7 +194,7 @@ public async Task Login(LoginUser loginUser) if (foundUser != null && foundUser.IsValidPassword(loginUser.Password)) { - // create a custom response + // Create a custom response var response = new { // This is the login token @@ -221,7 +221,7 @@ public async Task Login(LoginUser loginUser) } ``` -You'll notice the `POST` method doesn't take a `User` object, but a `loginUser` +You'll notice the `POST` method doesn't take a `User` object but a `loginUser` of type `LoginUser`. We need to do this since we **do** need to read the `Password` while the user is logging in. Thus we'll define this class inside the `SessionsController` to store the `Email` and `Password` strings. @@ -237,10 +237,10 @@ public class LoginUser The `POST` method attempts to find an existing user that has the same email address as the received user. -Next, it uses the `IsValidPassword` method we wrote in the `User` class to -detect if the password matches. +Next, it uses the `IsValidPassword` method, which we wrote in the `User` class +to detect if the password matches. -If we found a user `foundUser != null` **AND** the password matches we will +If we found a user `foundUser != null` **AND** the password matches, we will generate a response that looks like this: ```json @@ -262,7 +262,7 @@ dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer ``` We also include the `user` object in the response. Including the user object in -the response provides the client a simple way to access this data. +the response provides the client with a simple way to access this data. This custom object is the payload of the successful API response. @@ -277,7 +277,7 @@ we can try the same `email` and `password` to the `Sessions` endpoint and see if we get back a valid response. Try an invalid password or an email address that doesn't correspond to an account to see the error messages. -Next we'll connect the user interface to these controllers. +Next, we'll connect the user interface to these controllers.