Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to the index section #315

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions lessons/full-stack-build-an-app-adding-support-for-login/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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`
Expand All @@ -194,7 +194,7 @@ public async Task<ActionResult> 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
Expand All @@ -221,7 +221,7 @@ public async Task<ActionResult> 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.
Expand All @@ -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
Expand All @@ -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.

Expand All @@ -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.

<!-- Adds a sessions controller -->
<GithubCommitViewer repo="suncoast-devs/TacoTuesday" commit="fa9f88fd9cfaa50008b7af5bfab1884586de76e3" />