This project demonstrates how to implement JWT (JSON Web Token) authentication in a Spring Boot application with Spring Security using HTTP-only cookies for enhanced security. It includes user registration, login, and JWT token generation, along with password hashing using BCrypt. Additionally, the system sends a welcome email to users upon successful registration.
- Secure JWT authentication using HTTP-only cookies (XSS protection)
- BCrypt password encryption
- Email notification system for new user registration
- Spring Boot-based backend with Spring Security integration
- Role-based access control (USER/ADMIN roles)
- Easy-to-understand and extendable codebase
This implementation addresses security concerns by:
- Using HTTP-only cookies instead of localStorage/sessionStorage
- Preventing XSS attacks by making tokens inaccessible to JavaScript
- Automatic token transmission with every request
- Configurable cookie security settings (Secure, SameSite, HttpOnly)
- Spring Boot: Framework for building the application
- Spring Security: For securing the APIs
- JWT (JSON Web Token): For user authentication and token-based session management
- BCrypt: For secure password hashing
- Java Mail: For sending emails to users
- HTTP-only Cookies: For secure token storage
Before you begin, ensure you have met the following requirements:
- Java 8 or higher.
- Maven (for dependency management and build automation).
- Spring Boot 3.x.
- Access to an SMTP server for email functionality.
-
Clone the Repository:
git clone https://github.com/AjayKumbham/jwt-auth-api.git cd jwt-auth-api
-
Configure Application Properties:
Edit
src/main/resources/application.properties
to include your SMTP server configuration and JWT secret key.spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=your-email@example.com spring.mail.password=your-email-password jwt.secret=your-jwt-secret # JWT Cookie Configuration (for enhanced security) jwt.cookie.name=jwt-token jwt.cookie.max-age=1800 jwt.cookie.secure=true jwt.cookie.http-only=true jwt.cookie.same-site=Strict
Replace
your-email@example.com
,your-email-password
andyour-jwt-secret
with your actual details. -
Database Configuration
To configure the MySQL database, update the following properties in
src/main/resources/application.properties
:spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name spring.datasource.username=your_database_username spring.datasource.password=your_database_password spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
Replace
your_database_name
,your_database_username
, andyour_database_password
with your actual MySQL details. -
Build and Run the Application:
First, clean and install the dependencies by running:
mvn clean install
Using Maven, run the following command to build and start the application:
mvn spring-boot:run
The following are the available API endpoints in the application:
-
Method:
GET
-
Endpoint:
http://localhost:8080/auth/welcome
-
Description: A simple, non-secure endpoint to welcome users.
-
Response:
Welcome, this endpoint is not secure.
-
Method:
POST
-
Endpoint:
http://localhost:8080/auth/register
-
Description: Registers a new user. A welcome email is sent upon successful registration.
-
Request Body:
{ "username": "user123", "password": "password123", "email": "user@example.com", "roles":"ROLE_USER" }
-
Response:
User Added Successfully. A welcome email has been sent.
-
Method:
POST
-
Endpoint:
http://localhost:8080/auth/login
-
Description: Logs in the user and sets JWT token as HTTP-only cookie.
-
Request Body:
{ "username": "user123", "password": "password123" }
-
Response:
Login successful. JWT token set as HTTP-only cookie.
-
Security: The JWT token is automatically set as an HTTP-only cookie and will be sent with subsequent requests.
-
Method:
POST
-
Endpoint:
http://localhost:8080/auth/logout
-
Description: Logs out the user by clearing the JWT cookie.
-
Request: No body required (cookie is automatically sent)
-
Response:
Logout successful. JWT cookie cleared.
-
Method:
GET
-
Endpoint:
http://localhost:8080/auth/user/user-profile
-
Description: Fetches the user's profile information. Requires authentication (JWT cookie).
-
Request: No headers required (cookie is automatically sent)
-
Response:
Welcome to User Profile.
-
Method:
GET
-
Endpoint:
http://localhost:8080/auth/admin/admin-profile
-
Description: Fetches the admin's profile information. Requires authentication (JWT cookie) and ADMIN role.
-
Request: No headers required (cookie is automatically sent)
-
Response:
Welcome to Admin Profile.
You can use Postman to test the endpoints. Here are the steps for each:
-
Register User:
- Set the HTTP method to
POST
. - Use the
http://localhost:8080/auth/register
endpoint. - Add the request body as shown above.
- Press "Send" and check the response.
- Set the HTTP method to
-
Login:
- Set the HTTP method to
POST
. - Use the
http://localhost:8080/auth/login
endpoint. - Add the login credentials in the request body.
- Press "Send" - the JWT token will be set as an HTTP-only cookie automatically.
- Set the HTTP method to
-
Get User Profile:
- Set the HTTP method to
GET
. - Use the
http://localhost:8080/auth/user/user-profile
endpoint. - Press "Send" to view the profile data (cookie is automatically sent).
- Set the HTTP method to
-
Get Admin Profile:
- Set the HTTP method to
GET
. - Use the
http://localhost:8080/auth/admin/admin-profile
endpoint. - Press "Send" to view the admin profile data (cookie is automatically sent).
- Set the HTTP method to
-
Logout:
- Set the HTTP method to
POST
. - Use the
http://localhost:8080/auth/logout
endpoint. - Press "Send" to clear the JWT cookie.
- Set the HTTP method to
Note: With HTTP-only cookies, you don't need to manually manage tokens. The browser automatically sends the cookie with each request to the same domain.
screenshots of the API testing in Postman:
Here's how the JWT token is decoded using JWT.io.
After registering a user, you can verify the data in the MySQL UserInfo
table.
Contributions are welcome! If you have suggestions for improvements or bug fixes, please open an issue or submit a pull request.
- Fork the repository.
- Create a new branch (
git checkout -b feature/your-feature
). - Make your changes.
- Commit your changes (
git commit -am 'Add feature'
). - Push to the branch (
git push origin feature/your-feature
). - Create a new pull request.
This project is open-source and available under the MIT License.