indigotech / onboard-guilherme-brito

0 stars 0 forks source link

[Track 6/9] Login mutation #22

Open taki-tiler-server[bot] opened 2 months ago

taki-tiler-server[bot] commented 2 months ago

Step 1/5 - The mutation setup

Estimated time: 1 hour

In this track, you will implement a login mutation fully integrated with the database. There are many ways of implementing an authentication. The way we're doing it is: the user sends a password to prove that he is who he claims, and then the server provides a token that allows him to access some data on future requests. This token generally have an expiration, after which the user has to login again to get a new one.

This new mutation can be called login. It should receive an e-mail and a password as parameters and, in case of success, return the following structure on body:

{
  "data": {
    "login": {
      "user": {
        "id": 12,
        "name": "User Name",
        "email": "User e-mail",
        "birthDate": "04-25-1990",
      },
      "token": "the_token"
    }
  } 
}

For now, you can return the above structure directly on your code populated with some mock data.

NOTE: as a good practice, we recommend you create (or update) tests for this mutation after every step. This will help you create the right scenarios. Also, don't forget to open Pull Requests with the mutation and test codes.

GuiCastelo commented 2 months ago

Finish

taki-tiler-server[bot] commented 2 months ago

Step 2/5 - Integrating with the database

Estimated time: 2 hours

Now you're going to fully integrate the Login mutation with the database. Create a user with the createUser mutation so you can test it properly.

  1. Get the input e-mail received on the mutation and try to find one on database.
  2. Check if the given password is correct. Remember that: in order to compare them properly, the input password should be submitted to the same process of transformation that the ones stored on database, right?
  3. If the e-mail can be found on the database and the password is valid, return the user info and a token. For now, the token can be only an empty string. You're going to implement it on next step.

Also, you should consider our "error handling" subject and check for errors. Try to consider all relevant error cases.

GuiCastelo commented 2 months ago

Finish

taki-tiler-server[bot] commented 2 months ago

Step 3/5 - The token

Estimated time: 2 hours

Now you're going to finish your login mutation returning a proper token instead of an empty string. Take a look at an example of the token you're going to implement:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

This may look like a random string, but this token has a lot of power, because there are some information encoded in it. The server can know only with a token, for example:

  1. When it was created
  2. When it expires
  3. Which user is sending

This is an example of the famous JWT token. You're going to build this token and return it in your mutation. This link has some information about token based authentication, jwt tokens and an example of how to implement it on code.

Your task now is to implement a model of JWT tokens for your server and return them on your login mutation.

NOTE: generally, the payload of a JWT token only the minimum information for the server to idetify a user. So, for this case, only the user id is necessary.

GuiCastelo commented 2 months ago

Finish

taki-tiler-server[bot] commented 2 months ago

Step 4/5 - Challenge: the token duration

Estimated time: 2 hours

NOTE: some steps on this onboard are classified as "challenges". They are meant to be some additional tasks that add some bonus features, but are not necessarily core of the server. Try not to spend too much time on them 🙃

After implementing the login, you must have noticed that one of the possible parameters for creating a JWT token is the expiration. This parameter allows us set an expiration timestamp coded on the token. This challenge consists of:

  1. Adding an aditional optional parameter on the Login mutation called rememberMe. It's a boolean.
  2. If rememberMe was sent and its value is true, you should increase the expiration of the returned token. 1 week is good for our context.

Now your clients will have the oportunity to use that famous "Remember me" checkbox!

GuiCastelo commented 2 months ago

Finish

taki-tiler-server[bot] commented 2 months ago

Step 5/5 - The authentication

Estimated time: 2 hours

Now that you have a login mutation, let's explore the authentication. We're going to change the createUser mutation to be authenticated. This means that only authenticated users will be able to use this mutation. To check if a user is allowed to perform this operation, as you must imagine, we should receive and validate a JWT token. If it was properly signed by the system before, then we can execute the mutation code as intended.

Check the Authorization header: the client must have sent a JWT token and it should be a valid one. It's important to check if:

You can use a library to help you validate the token.

NOTE: bear in mind that anyone can create a JWT token with any payload data they want (remember jwt.io?), but only those who have the secret can generate the right signature. Only the server should know this secret.

If the JWT token has any problem, you should return an authentication error with a message.

TIP: create one more test case to validate this step, with the proper error checking if no token is sent (or an invalid one).

GuiCastelo commented 2 months ago

Finish

taki-tiler-server[bot] commented 2 months ago

Click here for your next track