The goal of this project is to implement an application called order-app
to manage orders. For it, we will implement a back-end Spring Boot
application called order-api
and a font-end React application called order-ui
. Besides, we will use JWT Authentication
to secure both applications.
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
- [Medium] Implementing A Full Stack Web App Using Spring-Boot and React
- [Medium] Implementing Social Login in a Spring Boot and React App
- [Medium] Building a Web Chat with Social Login using Spring Boot: Introduction
- [Medium] Building a Single Spring Boot App with Keycloak or Okta as IdP: Introduction
-
Spring Boot
Web Java backend application that exposes a Rest API to create, retrieve and delete orders. If a user hasADMIN
role he/she can also retrieve information of other users or delete them.The application secured endpoints can just be accessed if a valid JWT access token is provided.
order-api
stores its data inPostgres
database.order-api
has the following endpoints:Endpoint Secured Roles POST /auth/authenticate -d {"username","password"}
No POST /auth/signup -d {"username","password","name","email"}
No GET /public/numberOfUsers
No GET /public/numberOfOrders
No GET /api/users/me
Yes ADMIN
,USER
GET /api/users
Yes ADMIN
GET /api/users/{username}
Yes ADMIN
DELETE /api/users/{username}
Yes ADMIN
GET /api/orders [?text]
Yes ADMIN
POST /api/orders -d {"description"}
Yes ADMIN
,USER
DELETE /api/orders/{id}
Yes ADMIN
-
React
frontend application where a user with roleUSER
can create an order and retrieve a specific order. On the other hand, a user with roleADMIN
as access to all secured endpoints.In order to access the application, a
user
oradmin
must login using his/herusername
andpassword
. All the requests coming fromorder-ui
to secured endpoints inorder-api
have the JWT access token. This token is generated when theuser
oradmin
logins.order-ui
usesSemantic UI React
as CSS-styled framework.
-
In a terminal, make sure you are inside
springboot-react-jwt-token
root folder; -
Run the following command to start docker compose services:
docker compose up -d
-
order-api
-
Open a terminal and navigate to
springboot-react-jwt-token/order-api
folder; -
Run the following
Maven
command to start the application:./mvnw clean spring-boot:run
-
-
order-ui
-
Open another terminal and navigate to
springboot-react-jwt-token/order-ui
folder; -
Run the command below if you are running the application for the first time:
npm install
-
Run the
npm
command below to start the application:npm start
-
Application | URL | Credentials |
---|---|---|
order-api | http://localhost:8080/swagger-ui.html | |
order-ui | http://localhost:3000 | admin/admin , user/user or signing up a new user |
Note: the credentials shown in the table are the ones already pre-defined. You can signup new users.
-
Manual Endpoints Test using Swagger
-
Open a browser and access http://localhost:8080/swagger-ui.html. All endpoints with the lock sign are secured. In order to access them, you need a valid JWT access token;
-
Click
POST /auth/authenticate
and then, clickTry it out
button; -
Provide the
user
credentialsusername
andpassword
:{ "password": "user", "username": "user" }
-
Click
Execute
button. It should return something like:Code: 200 { "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9..." }
Note 1: You can use the
admin
credentials to access more secured endpoints.Note 2: The token will expire in 10 minutes.
-
Copy the
accessToken
value (without the double quotes); -
Click the
Authorize
button at the top of the page; -
In
Value
input field, paste the copied token; -
Click
Authorize
button and then, clickClose
button; -
To create an order, click
POST /api/orders
and then, clickTry it out
button; -
Provide the
description
of the order:{ "description": "Buy two iPhones" }
-
Click
Execute
button. It should return something like:Code: 200 { "id": "718c9f40-5c06-4571-bc3e-3f888c52eff2", "description": "Buy two iPhones", "user": { "username": "user" }, "createdAt": "..." }
-
-
Manual Endpoints Test using curl
-
Open a terminal;
-
Call
GET /public/numberOfUsers
:curl -i localhost:8080/public/numberOfUsers
It should return:
HTTP/1.1 200 2
-
Call
GET /api/orders
without JWT access token:curl -i localhost:8080/api/orders
As for this endpoint a valid JWT access token is required, it should return:
HTTP/1.1 401
-
Call
POST /auth/authenticate
to getadmin
JWT access token:ADMIN_ACCESS_TOKEN="$(curl -s -X POST http://localhost:8080/auth/authenticate \ -H 'Content-Type: application/json' \ -d '{"username": "admin", "password": "admin"}' | jq -r .accessToken)"
-
Call again
GET /api/orders
, now withadmin
JWT access token:curl -i -H "Authorization: Bearer $ADMIN_ACCESS_TOKEN" localhost:8080/api/orders
It should return an empty array or an array with orders:
HTTP/1.1 200 [ ... ]
-
Call
GET /api/users/me
to get more information about theadmin
:curl -i -H "Authorization: Bearer $ADMIN_ACCESS_TOKEN" localhost:8080/api/users/me
It should return:
HTTP/1.1 200 { "id": 1, "username": "admin", "name": "Admin", "email": "[email protected]", "role": "ADMIN", "orders": [] }
-
-
Automatic Endpoints Test
-
Open a terminal and make sure you are in
springboot-react-jwt-token
root folder; -
Run the following script:
./order-api/test-endpoints.sh
It should return something like the output below, where it shows the http code for different requests:
POST auth/authenticate ====================== admin access token ------------------ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCI6MTU4Nj..._ha2pM4LSSG3_d4exgA user access token ----------------- eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCIyOSwian...Y3z9uwhuW_nwaGX3cc5A POST auth/signup ================ user2 access token ------------------ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImanRpIjoiYTMw...KvhQbsMGAlFov1Q480qg Authorization ============= Endpoints | without token | user token | admin token | ------------------------- + ------------- + ----------- + ------------ | GET public/numberOfUsers | 200 | 200 | 200 | GET public/numberOfOrders | 200 | 200 | 200 | ......................... + ............. + ........... + ............ | GET /api/users/me | 401 | 200 | 200 | GET /api/users | 401 | 403 | 200 | GET /api/users/user2 | 401 | 403 | 200 | DELETE /api/users/user2 | 401 | 403 | 200 | ......................... + ............. + ........... + ............ | GET /api/orders | 401 | 403 | 200 | POST /api/orders | 401 | 201 | 201 | DELETE /api/orders/{id} | 401 | 403 | 200 | ------------------------------------------------------------------------ [200] Success - [201] Created - [401] Unauthorized - [403] Forbidden
-
-
Postgres
docker exec -it postgres psql -U postgres -d orderdb \dt
-
jwt.io
With jwt.io you can inform the JWT token and the online tool decodes the token, showing its header and payload.
-
To stop
order-api
andorder-ui
, go to the terminals where they are running and pressCtrl+C
; -
To stop and remove docker compose containers, network and volumes, go to a terminal and, inside:
springboot-react-jwt-token
root folder, run the command belowdocker compose down -v
-
In a terminal, make sure you are in
springboot-react-jwt-token/order-ui
folder; -
Run the following commands:
npm upgrade npm i -g npm-check-updates ncu -u npm install