How node returns user with token to React

We start off on the frontend, where we submit some data.

frontend – src/pages/Register.jsx

we dispatch register with userData, via createAsyncThunk. createAsyncThunk creates an async request. It generates promise lifecycle action types pending/fulfilled/rejected.

We start the process by defining a payload creator, which is the anon function provided to createAsyncThunk. It tries to execute our authServer.register function.

frontend – src/features/auth/authSlice.js

This allows us to use axios’s post and hit the URL with the body data.

frontend – src/features/auth/authService.js

The request is received on the backend.

When we request to register a user, Node receives the request and data in the body.
If the username doesn’t exist, it would create the user, and then generate a token.
It would return the newly created user data and the generated token back to the front end.

backend – backend/controllers/userController.js

In order to generate the token, it would take the user’s id, the JWT_SECRET string, and create a token by using the sign function.

JWTs can be signed using a secret (in our case JWT_SECRET string) with the HMAC algorithm.
It will spit back a long jwt token string.

This string can only be decrypted with the same string.

The reason why we do this is because we want the front end to use the same token and send it back to use, which needs to be decrypted by using the same JWT_SECRET:

backend/middleware/authMiddleware.js

We can then get the user’s id and find it in our database. This ensures that the client making the request is someone we have dealt with before.

Newly created user and token arrives in React

we return the data to the async anon function that is the 2nd parameter of createAsyncThunk:

This will return to our state’s user object via action.payload when our register thunk’s promise has been fullfilled:

This is how our thunkAPI’s can access the token from its user object in the state.

The thunk can access the store (getState) and accesses its reducer auth, which then accesses its state property user, and finally, the token property.

The user comes from the state:

And the auth is the reducer’s property name in the store: