Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ivangfr/springboot-react-jwt-token
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.
https://github.com/ivangfr/springboot-react-jwt-token
docker java javascript jsonwebtoken jtw jwt-authentication postgresql react semantic-ui-react spring-boot spring-data-jpa spring-security spring-web-mvc springdoc-openapi
Last synced: 2 days ago
JSON representation
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.
- Host: GitHub
- URL: https://github.com/ivangfr/springboot-react-jwt-token
- Owner: ivangfr
- Created: 2020-04-10T12:04:48.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-12-12T13:10:41.000Z (11 days ago)
- Last Synced: 2024-12-12T14:21:47.769Z (11 days ago)
- Topics: docker, java, javascript, jsonwebtoken, jtw, jwt-authentication, postgresql, react, semantic-ui-react, spring-boot, spring-data-jpa, spring-security, spring-web-mvc, springdoc-openapi
- Language: Java
- Homepage:
- Size: 8.21 MB
- Stars: 164
- Watchers: 8
- Forks: 51
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
# springboot-react-jwt-token
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`](https://docs.spring.io/spring-boot/index.html) application called `order-api` and a font-end [React](https://react.dev/) application called `order-ui`. Besides, we will use [`JWT Authentication`](https://en.wikipedia.org/wiki/JSON_Web_Token) to secure both applications.
## Proof-of-Concepts & Articles
On [ivangfr.github.io](https://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.
## Additional Readings
- \[**Medium**\] [**Implementing A Full Stack Web App Using Spring-Boot and React**](https://medium.com/@ivangfr/implementing-a-full-stack-web-app-using-spring-boot-and-react-7db598df4452)
- \[**Medium**\] [**Implementing Social Login in a Spring Boot and React App**](https://medium.com/@ivangfr/implementing-social-login-in-a-spring-boot-and-react-app-6ce073c9983c)
- \[**Medium**\] [**Building a Web Chat with Social Login using Spring Boot: Introduction**](https://medium.com/@ivangfr/building-a-web-chat-with-social-login-using-spring-boot-introduction-644702e6be8e)
- \[**Medium**\] [**Building a Single Spring Boot App with Keycloak or Okta as IdP: Introduction**](https://medium.com/@ivangfr/building-a-single-spring-boot-app-with-keycloak-or-okta-as-idp-introduction-2814a4829aed)## Project Diagram
![project-diagram](documentation/project-diagram.jpeg)
## Applications
- ### order-api
`Spring Boot` Web Java backend application that exposes a Rest API to create, retrieve and delete orders. If a user has `ADMIN` 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 in [`Postgres`](https://www.postgresql.org/) 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` |- ### order-ui
`React` frontend application where a user with role `USER` can create an order and retrieve a specific order. On the other hand, a user with role `ADMIN` as access to all secured endpoints.
In order to access the application, a `user` or `admin` must login using his/her `username` and `password`. All the requests coming from `order-ui` to secured endpoints in `order-api` have the JWT access token. This token is generated when the `user` or `admin` logins.
`order-ui` uses [`Semantic UI React`](https://react.semantic-ui.com/) as CSS-styled framework.## Prerequisites
- [`npm`](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
- [`Java 21+`](https://www.oracle.com/java/technologies/downloads/#java21)
- Some containerization tool [`Docker`](https://www.docker.com/), [`Podman`](https://podman.io/), etc.
- [`jq`](https://jqlang.github.io/jq/)## Start Environment
- In a terminal, make sure you are inside the `springboot-react-jwt-token` root folder;
- Run the following command to start docker compose containers:
```
docker compose up -d
```## Running order-app using Maven & Npm
- **order-api**
- Open a terminal and navigate to the `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 the `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
```## Applications URLs
| 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.
## Demo
- The gif below shows a `user` loging in:
![user-login](documentation/user-login.gif)
- The gif below shows an `admin` loging in:
![admin-login](documentation/admin-login.gif)
## Testing order-api Endpoints
- **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, click `Try it out` button;
- Provide the `user` credentials `username` and `password`:
```
{ "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, click `Close` button;
- To create an order, click `POST /api/orders` and then, click `Try 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 get `admin` 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)"
echo $ADMIN_ACCESS_TOKEN
```- Call again `GET /api/orders`, now with `admin` 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 the `admin`:
```
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 the `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
```## Util Commands
- **Postgres**
```
docker exec -it postgres psql -U postgres -d orderdb
\dt
```- **jwt.io**
With [jwt.io](https://jwt.io) you can inform the JWT token and the online tool decodes the token, showing its header and payload.
## Shutdown
- To stop `order-api` and `order-ui`, go to the terminals where they are running and press `Ctrl+C`;
- To stop and remove docker compose containers, network and volumes, go to a terminal and, inside the `springboot-react-jwt-token` root folder, run the command below:
```
docker compose down -v
```## How to upgrade order-ui dependencies to latest version
- In a terminal, make sure you are in the `springboot-react-jwt-token/order-ui` folder;
- Run the following commands:
```
npm upgrade
npm i -g npm-check-updates
ncu -u
npm install
```## References
- https://www.callicoder.com/spring-boot-security-oauth2-social-login-part-2/#jwt-token-provider-authentication-filter-authentication-error-handler-and-userprincipal
- https://bezkoder.com/spring-boot-jwt-authentication/
- https://dev.to/keysh/spring-security-with-jwt-3j76