The goal of this project is to implement an application called order-app to manage orders. For it, we will implement a back-end application called order-api using Spring Boot and a font-end application called order-ui using ReactJS. Besides, we will use JWT Authentication to secure both applications.
-
Spring BootWeb Java backend application that exposes a Rest API to create, retrieve and delete orders. If a user hasADMINrole 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-apistores its data inMySQLdatabase.order-apihas the following endpointsEndpoint Secured Roles POST /auth/authenticate -d {"username","password"}No POST /auth/signup -d {"username","password","name","email"}No GET /public/numberOfUsersNo GET /public/numberOfOrdersNo GET /api/users/meYes ADMIN,USERGET /api/usersYes ADMINGET /api/users/{username}Yes ADMINDELETE /api/users/{username}Yes ADMINGET /api/orders [?text]Yes ADMINPOST /api/orders -d {"description"}Yes ADMIN,USERDELETE /api/orders/{id}Yes ADMIN -
ReactJSfrontend application where a user with roleUSERcan create an order and retrieve a specific order. On the other hand, a user with roleADMINas access to all secured endpoints.In order to access the application, a
useroradminmust login using his/herusernameandpassword. All the requests coming fromorder-uito secured endpoints inorder-apihave the JWT access token. This token is generated when theuseroradminlogins.order-uiusesSemantic UI Reactas CSS-styled framework.
-
Open a terminal and inside
springboot-react-jwt-tokenroot folder rundocker-compose up -d -
Wait a little bit until
mysqlcontainer is Up (healthy). You can check their status runningdocker-compose ps
-
order-api
-
Open a terminal and navigate to
springboot-react-jwt-token/order-apifolder -
Run the following
Mavencommand to start the application./mvnw clean spring-boot:run
-
-
order-ui
-
Open another terminal and navigate to
springboot-react-jwt-token/order-uifolder -
Run the command below if you are running the application for the first time
npm install -
Run the
npmcommand below to start the applicationnpm 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 on
auth-controller, then onPOST /auth/authenticateand, finally, onTry it out -
Provide the
usercredentialsusernameandpasswordand click onExecutebutton{ "password": "user", "username": "user" }It should return something like
Code: 200 { "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9..." }Note 1: You can use the
admincredentials to access more secured endpointsNote 2: The token will expire in 10 minutes
-
Copy the
accessTokenvalue (without the double quotes) -
Click on the
Authorizebutton on the top of the page -
On
Valueinput field, paste the copied token -
Click on
Authorizeand then onClose -
To create an order, click on
order-controller. Then, click onPOST /api/ordersand onTry it out -
Provide the
descriptionof the order{ "description": "Buy two iPhones" } -
Click on
Executebutton. It should return something likeCode: 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/numberOfUserscurl -i localhost:8080/public/numberOfUsersIt should return
HTTP/1.1 200 2 -
Call
GET /api/orderswithout JWT access tokencurl -i localhost:8080/api/ordersAs for this endpoint a valid JWT access token is required, it should return
HTTP/1.1 401 -
Call
POST /auth/authenticateto getadminJWT access tokenADMIN_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 withadminJWT access tokencurl -i -H "Authorization: Bearer $ADMIN_ACCESS_TOKEN" localhost:8080/api/ordersIt should return an empty array or an array with orders
HTTP/1.1 200 [ ... ] -
Call
GET /api/users/meto get more information about theadmincurl -i -H "Authorization: Bearer $ADMIN_ACCESS_TOKEN" localhost:8080/api/users/meIt should return
HTTP/1.1 200 { "id": 1, "username": "admin", "name": "Admin", "email": "admin@mycompany.com", "role": "ADMIN", "orders": [] }
-
-
Automatic Endpoints Test
-
Open a terminal and make sure you are in
springboot-react-jwt-tokenroot folder -
Run the following script
./order-api/test-endpoints.shIt should return something like the output below, where it shows the http code for different requests
GET auth/authenticate ===================== admin access token ------------------ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCI6MTU4Nj..._ha2pM4LSSG3_d4exgA user access token ----------------- eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCIyOSwian...Y3z9uwhuW_nwaGX3cc5A GET 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
-
-
MySQL
docker exec -it mysql mysql -uroot -psecret --database=orderdb show tables; -
jwt.io
With jwt.io you can inform the JWT token and the online tool decodes the token, showing its header and payload.
-
Go to
order-apiandorder-uiterminals and pressCtrl+Con each one -
To stop and remove docker-compose containers, networks and volumes, run the command below in
springboot-react-jwt-tokenroot folderdocker-compose down -v
-
In a terminal, make sure you are in
springboot-react-jwt-token/order-uifolder -
Run the following commands
npm i -g npm-check-updates ncu -u npm install

