Skip to content

Commit 82f4526

Browse files
authored
Chapter 04 corrigé Lorène
1 parent 622647b commit 82f4526

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

rails6/en/chapter04-athentification.adoc

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ You can clone the project up to this point:
1212
$ git checkout tags/checkpoint_chapter04
1313
----
1414

15-
In this chapter things will get very interesting because we are going to set up our authentication mechanism. In my opinion this is going to be one of the most interesting chapters. We will introduce a lot of new terms and you will end with a simple but powerful authentication system. Don’t feel panic we will get to that.
15+
In this chapter things will get very interesting because we are going to set up our authentication mechanism. In my opinion it's one of the most interesting chapters. We will introduce a lot of new terms and you will end with a simple but powerful authentication system. Don’t feel panic we will get to that.
1616

1717
First things first (and as usual when starting a new chapter) we will create a new branch:
1818

@@ -29,11 +29,11 @@ The flow for authenticating the user through an API is very simple:
2929

3030
. The client request for `sessions` resource with the corresponding credentials, usually email and password.
3131
. The server returns the `user` resource along with its corresponding authentication token
32-
. Every page that requires authentication, the client has to send that `authentication token`
32+
. For every page that requires authentication the client has to send that `authentication token`
3333

34-
Of course this is not the only 3-step to follow, and even on step 2 you might think, well do I really need to respond with the entire user or just the `authentication token`, I would say, it really depends on you, but I like to return the entire user, this way I can map it right away on my client and save another possible request from being placed.
34+
Of course this is not the only 3-step to follow, and even on step 2 you might think, well do I really need to respond with the entire user or just the `authentication token` ? I would say, it really depends on you, but I like to return the entire user, this way I can map it right away on my client and save another possible request from being placed.
3535

36-
In this section and the next we will be focusing on building a Sessions controller along with its corresponding actions. We’ll then complete the request flow by adding the necessary authorization access.
36+
This section and the next we will be focusing on building a Sessions controller along with its corresponding actions. We’ll then complete the request flow by adding the necessary authorization access.
3737

3838

3939
=== JWT presentation
@@ -44,9 +44,9 @@ When it comes to authentication tokens, there is a standard: the JSON Web Token
4444

4545
Overall, a JWT token is composed of three parts:
4646

47-
- a *header* structured in JSON which will contain for example the validity date of the token.
48-
- a _payload_ structured in JSON that can contain *any data*. In our case, it will contain the identifier of the "connected" user.
49-
- a *signature* that will allow us to verify that the token has been encrypted by our application and is therefore valid.
47+
- a *header* structured in JSON contains for example the validity date of the token.
48+
- a _payload_ structured in JSON can contain *any data*. In our case, it will contain the identifier of the "connected" user.
49+
- a *signature* allows us to verify that the token has been encrypted by our application and is therefore valid.
5050

5151
These three parts are each encoded in base64 and then concatenated using points (`.`). Which gives us something like that:
5252

@@ -71,7 +71,7 @@ Once decoded, this token gives us the following information:
7171

7272
NOTE: For more information about JWT tokens I invite you to visit https://jwt.io[jwt.io]
7373

74-
This has many advantages such as sending information in token's payload. For example, we may choose to integrate the user's information into the _payload_.
74+
This has many advantages such as sending information in token's payload. For example, we may choose to integrate user's information into the _payload_.
7575

7676
=== Setting up the authentication token
7777

@@ -100,9 +100,9 @@ The library is very simple. There are two methods: `JWT.encode` and `JWT.decode`
100100
=> [{"message"=>"Hello World"}, {"alg"=>"HS256"}]
101101
----
102102

103-
In the first line we encoded a _payload_ with the secret key _my_secret_key_. So we get a token that we can simply decode. The second line decodes the token and we see that we find our _payload_ well.
103+
In the first line we encoded a _payload_ with the secret key _my_secret_key_. So we get a token we can simply decode. The second line decodes the token and we see that we find our _payload_ well.
104104

105-
We will now include all this logic in a `JsonWebToken` class in a new file located in `lib/`. This will allow us to avoid duplicating the code. This class will just encode and decode the JWT tokens. So here is the implementation.
105+
We will now include all this logic in a `JsonWebToken` class in a new file located in `lib/`. This will allow us to avoide duplicating the code. This class will just encode and decode the JWT tokens. So here is the implementation.
106106

107107
.lib/json_web_token.rb
108108
[source,ruby]
@@ -124,8 +124,8 @@ end
124124

125125
I know that's a lot of code but we're going to review it together.
126126

127-
- the method `JsonWebToken.encode` will take care of encoding the _payload_ by adding an expiration date of 24 hours by default. We also use the same encryption key as the one configured with Rails
128-
- the method `JsonWebToken.decode` will decode the JWT token and get the _payload_. We then use the https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html[`HashWithIndifferentAccess`] class provided by Rails which allows us to retrieve a value of a `Hash` with a `Symbol` or `String`.
127+
- the method `JsonWebToken.encode` takes care of encoding the _payload_ by adding an expiration date of 24 hours by default. We also use the same encryption key as the one configured with Rails
128+
- the method `JsonWebToken.decode` decodes the JWT token and gets the _payload_. Then we use the https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html[`HashWithIndifferentAccess`] class provided by Rails which allows us to retrieve a value of a `Hash` with a `Symbol` or `String`.
129129

130130
There you go. In order to load the file into our application, you must specify the `lib` folder in the list of Ruby on Rails _autoload_s. To do this, add the following configuration to the `application.rb` file:
131131

@@ -151,7 +151,7 @@ $ git add . && git commit -m "Setup JWT gem"
151151

152152
=== Token's controller
153153

154-
We have therefore set up the system for generating a JWT token. It is now time to create a route that will generate this token. The actions we will implement will be managed as _RESTful_ services: the connection will be managed by a POST request to the `create` action.
154+
We have therefore set up the system for generating a JWT token. It's now time creating a route that will generate this token. The actions we will implement will be managed as _RESTful_ services: the connection will be managed by a POST request to the `create` action.
155155

156156
To start, we will start by creating the controller of and method `create` in the _namespace_ `/api/v1`. With Rails, one order is sufficient:
157157

@@ -238,7 +238,7 @@ Failure:
238238
Expected response to be a <401: unauthorized>, but was a <204: No Content>
239239
----
240240

241-
That's normal. It is now time to implement the logic to create the JWT token. It is very simple.
241+
That's normal. It's now time implementing the logic to create the JWT token. It is very simple.
242242

243243
.config/routes.rb
244244
[source,ruby]
@@ -267,10 +267,10 @@ end
267267

268268
That's a lot of code but it's very simple:
269269

270-
. We always filter the parameters with the method `user_params`.
270+
. We always filter parameters with the method `user_params`.
271271
. We retrieve the user with the method `User.find_by_email` (which is a "magic" method of _Active Record_ since the field `email` is present in the database) and we retrieve the user
272272
. We use the method `User#authenticate` (which exists thanks to the gem `bcrypt`) with the password as a parameter. Bcrypt will _hash_ password and check if it matches the attribute `password_digest`. The function returns `true` if everything went well, `false` if not.
273-
. In the case where the password corresponds to the _hash_, a JSON containing the _token_ generated with the class `JsonWebToken` is returned. Otherwise, an empty response is returned with an `unauthorized` header
273+
. If the password corresponds to the _hash_, a JSON containing the _token_ generated with the class `JsonWebToken` is returned. Otherwise, an empty response is returned with an `unauthorized` header
274274

275275
Are you still here? Don't worry, it's over! Now your tests must pass.
276276

@@ -296,13 +296,15 @@ $ git add . && git commit -m "Setup tokens controller"
296296

297297
So we implemented the following logic: API returns the authentication token to the client if credentials are correct .
298298

299-
We will now implement the following logic: Each time this client requests a protected page, we will have to find the user from this authentication token that the user has passed in the HTTP header.
299+
We will now implement the following logic: Each time this client requests a protected page, we'll have to find the user from this authentication token that the user has passed in the HTTP header.
300+
301+
//pas compris
300302

301303
In our case, we will use the HTTP header `Authorization` which is often used for this. Personally, I find it the best way because it gives context to the request without polluting the URL with additional parameters.
302304

303305
We will therefore create a `current_user` method to meet our needs. It will find the user thanks to his authentication token which is sent on each request.
304306

305-
When it comes to authentication, I like to add all the associated methods in a separate file. Then simply include the file in the `ApplicationController`. In this way, it is very easy to test in isolation. Let's create the file in the `controllers/concerns` directory with a `current_user` method that we will implement right after:
307+
When it comes to authentication, I like adding all the associated methods in a separate file. Then simply include the file in the `ApplicationController`. In this way, it's very easy to test in isolation. Let's create the file in the `controllers/concerns` directory with a `current_user` method that we will implement right after:
306308

307309
[source,ruby]
308310
.app/controllers/concerns/authenticable.rb
@@ -323,7 +325,7 @@ $ mkdir test/controllers/concerns
323325
$ touch test/controllers/concerns/authenticable_test.rb
324326
----
325327

326-
As usual, we start by writing our tests. In this case, our `current_user` method will search for a user by the authentication token in the HTTP header `Authorization`. The test is quite basic:
328+
As usual, we start by writing our tests. In this case, our `current_user` method will search for an user by the authentication token in the HTTP header `Authorization`. The test is quite basic:
327329

328330
[source,ruby]
329331
.test/controllers/concerns/authenticable_test.rb
@@ -444,7 +446,7 @@ $ git add . && git commit -m "Adds authenticable module for managing authenticat
444446

445447
== Authentication with the token
446448

447-
Authorization plays an important role in the construction of applications because, unlike authentication, which identifies the user, authorization helps us define what he or she is allowed to do.
449+
Authorization plays an important role in the construction of applications because it helps us define what user is allowed to do.
448450

449451
We have a route to update the user but there is a problem: anyone can update any user. In this section, we will implement a method that will require the user to be logged in to prevent unauthorized access.
450452

@@ -477,7 +479,7 @@ class Api::V1::UsersControllerTest < ActionDispatch::IntegrationTest
477479
end
478480
----
479481

480-
You can see that now we have to add a header _Authorization_ for the user's modification action. We want to receive a _forbidden_ response if we don't .
482+
You can see now we have to add a header _Authorization_ for the user's modification action. We want to receive a _forbidden_ response if we don't .
481483

482484
We can imagine about the same thing for the test _should forbid destroy user_:
483485

0 commit comments

Comments
 (0)