A full-stack, secure authentication system built with Spring Boot, featuring JWT tokens, email verification, password reset, and OAuth2 social logins (Google & GitHub). The frontend uses Thymeleaf with responsive Tailwind CSS for modern, mobile-friendly UI. Powered by H2 in-memory DB for quick prototyping (easy swap to MySQL/PostgreSQL).
This project demonstrates best practices for stateless auth in microservices/APIs, with extensible code for production. Includes user-friendly pages for login, register, and dashboard with seamless flows.
- JWT Authentication: Stateless tokens (1-hour expiry) for secure API access.
- User Registration: Flexible fields (firstName, lastName, email, password); auto-roles ("USER").
- Email Verification: Post-registration email with one-time link (using Spring Mail/Gmail).
- Password Reset: "Forgot Password" flow with expiring tokens (1-hour).
- OAuth2 Social Login: One-click sign-in with Google & GitHub (auto-saves users to DB).
- Protected Dashboard: Role-based access; displays user data post-login.
- Responsive UI: Tailwind CSSβstacks on mobile, grids on desktop/tablet.
- Security: BCrypt hashing, CSRF disabled (enable in prod), verified-only logins.
- Database: H2 (embedded)βview data via console; JPA auto-schema.
A clean form for new users with responsive fields (name, email, password). Mobile: Stacked; Desktop: Grid layout.

(Screenshot: Form with Tailwind stylingβfirst/last name side-by-side on larger screens.)
Includes email/password form, "Forgot Password" link, and social buttons (Google/GitHub). Errors show in red banners.

(Screenshot: Social buttons stack on mobile; error message for invalid creds.)
Protected view showing welcome message, user email/full name, and logout button. Responsive cards for data.
(Screenshot: Personalized greetingβ"Welcome, John Doe!" with email; logout button aligned right on desktop.)
(Add real screenshots to GitHub repo by uploading to docs/ folder and updating links.)
- Java 17+ (JDK installed; use SDKMAN or Oracle/OpenJDK).
- Maven 3.6+ (for build/run).
- IDE: IntelliJ IDEA, VS Code, or Eclipse (optional, but recommended for Thymeleaf previews).
- Gmail Account (for email testing; enable 2FA + generate app passwordβsee guide below).
- Google & GitHub OAuth Apps (see Configuration below).
No Node.js or frontend build toolsβTailwind via CDN for simplicity.
Follow these steps to get running in <10 minutes.
- Visit start.spring.io.
- Project: Maven Project.
- Language: Java.
- Spring Boot: 3.3.3 (latest stable).
- Group:
com.example. - Artifact:
simple-auth. - Name:
simple-auth. - Package name:
com.example.simpleauth. - Packaging: Jar.
- Java: 17.
- Dependencies: Add these (search & select):
- Spring Web
- Spring Security
- Spring Data JPA
- H2 Database
- Thymeleaf
- Validation
- Spring Boot Starter Mail (for emails)
- OAuth2 Client (for Google/GitHub)
- Click Generate β Download ZIP β Extract to a folder named
simple-auth-project.
- Open the extracted folder in your IDE (e.g., IntelliJ: Open β select folder).
- Replace/Add Files: Copy the complete code from the Final Code Guide into the corresponding paths.
pom.xml: Update with JJWT dependencies.- Java classes: In
src/main/java/com/example/simpleauth/(controllers, entities, etc.). - Properties:
src/main/resources/application.properties. - Templates:
src/main/resources/templates/(login.html, register.html, dashboard.html, etc.). - Static:
src/main/resources/static/js/app.js(JS helpers).
- Folder Structure Overview (after adding):
simple-auth-project/ βββ pom.xml βββ src/ β βββ main/ β βββ java/com/example/simpleauth/ β β βββ SimpleAuthApplication.java β β βββ config/ (SecurityConfig.java, PasswordConfig.java, etc.) β β βββ controller/ (AuthController.java, DashboardController.java, etc.) β β βββ entity/ (User.java) β β βββ repository/ (UserRepository.java) β β βββ service/ (UserService.java) β β βββ util/ (JwtUtils.java) β β βββ mail/ (EmailService.java) β βββ resources/ β βββ application.properties β βββ static/js/app.js β βββ templates/ (login.html, register.html, dashboard.html, etc.) βββ README.md
Edit src/main/resources/application.properties (never commit real secretsβuse .gitignore):
# H2 Database (In-Memory)
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true # Access: http://localhost:8080/h2-console
# Thymeleaf (Dev)
spring.thymeleaf.cache=false
# JWT
app.jwtSecret=${JWT_SECRET:dev-secret-only} # Use env var in prod
app.baseUrl=http://localhost:8080
# Mail (Gmail - App Password Required)
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${MAIL_USERNAME:your-gmail@gmail.com}
spring.mail.password=${MAIL_PASSWORD:your-app-password}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
# Google OAuth
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID:mock}
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET:mock}
spring.security.oauth2.client.registration.google.scope=openid,email,profile
# GitHub OAuth
spring.security.oauth2.client.registration.github.client-id=${GITHUB_CLIENT_ID:mock}
spring.security.oauth2.client.registration.github.client-secret=${GITHUB_CLIENT_SECRET:mock}
spring.security.oauth2.client.registration.github.scope=user:email
spring.security.oauth2.client.provider.github.user-name-attribute=login
# Logging
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.mail=DEBUG- Env Vars Setup: In IDE (IntelliJ): Run Config β Modify β Environment Variables β Add keys/values.
- Gmail App Password: Follow this guide to generate (required for SMTP).
- OAuth Creds: From Google/GitHub consoles (see Usage below).
- Terminal in project root:
mvn clean install(downloads deps). - Start:
mvn spring-boot:run. - App:
http://localhost:8080(redirects to/login). - H2 Console:
http://localhost:8080/h2-console(JDBC:jdbc:h2:mem:testdb; view users).
Test the full flowβeach feature is independent but integrated.
- Go to
http://localhost:8080/register. - Fill: First Name (John), Last Name (Doe), Email (john@example.com), Password (123456).
- Submit β Alert: "Registered! Check email to verify."
- Backend: User saved unverified; token + email sent.
- Check inbox/spam for "Verify Your Email" (link:
http://localhost:8080/verify?token=...). - Click β Redirect to
/verify-success: "Email Verified! Go to Login." - Backend: Token validated; user marked verified.
- Go to
http://localhost:8080/login. - Enter email/password β Submit.
- Success: Token in localStorage β Redirect to
/dashboard. - Errors: Invalid β Red banner. Unverified β "Email not verified."
- On
/login, click "Sign in with Google" or "Sign in with GitHub." - Auth on provider β Redirect back β Auto-JWT + dashboard.
- First Time: User auto-created (email from provider, verified=true).
- On
/login, click "Forgot Password?" β/forgot-password. - Enter email β Submit β "Reset email sent!"
- Click link in email β
/reset-passwordβ New password β Redirect to login.
- Post-login:
/dashboardshows "Welcome, [Full Name]!" + email + logout. - Protected: Unauthorized β Back to login.
- Java Packages:
config/: Security, web configs (JWT filter, OAuth).controller/: Handles routes (auth, dashboard, verify, forgot/reset).entity/:User.java(implements UserDetails + OAuth2User).repository/:UserRepository.java(JPA queries).service/:UserService.java(load/save, tokens, OAuth save).util/:JwtUtils.java(token gen/validate).mail/:EmailService.java(verification/reset emails).
- Resources:
application.properties: All configs (externalize secrets!).templates/: Thymeleaf HTML (login.html, etc.) with Tailwind.static/js/app.js: Form validation, token storage (fetch API).
- Add User Fields: Extend
User(e.g.,phone), update forms/repo/service. - Real Database: Change
spring.datasource.urlto MySQL; add dep. - More OAuth: Add Facebook in properties + button in login.html.
- Refresh Tokens: Extend
JwtUtilswith renewal endpoint. - Production:
- Enable CSRF: In SecurityConfig.
- HTTPS: Use Nginx proxy.
- Secrets: Env vars or AWS Secrets Manager.
- Tailwind Build: npm install tailwindcss β Build CSS for offline.
| Issue | Solution |
|---|---|
| Build Fails | mvn clean install; check Java 17. |
| Port Busy | server.port=8081 in properties. |
| No Email | Check Gmail App Password (guide above); add logging.level.org.springframework.mail=DEBUG. |
| OAuth Error | Verify URIs in Google/GitHub console; add test users. |
| JWT Invalid | Regenerate secret; check localStorage (F12). |
| H2 Missing | spring.jpa.hibernate.ddl-auto=update; restart. |
Logs: Console shows DEBUGβsearch "Security" or "Mail".
MITβfree to use/modify. See LICENSE.
Fork β Changes β PR. Issues welcome!
Built with β€οΈ using Spring Boot (Nov 2025). Questions? Check comments or issues.