How I Secured My Vue + Spring Boot Application with JWT
When I first connected Vue with Spring Boot, everything worked—but there was one big problem: anyone could access my APIs.

In the previous post, I connected a Vue frontend with a Spring Boot backend. That worked fine for basic communication, but there was one major gap—anyone could access the APIs.
In this article, I’ll walk through how I added authentication using JWT so that only logged-in users can interact with the backend.
🔐 Why I Chose JWT
When I started looking into authentication, I had two main options:
Session-based authentication
Token-based authentication
I went with JWT because:
I didn’t want to maintain sessions on the server
It works cleanly with frontend frameworks like Vue
It’s easier to scale later
The idea is simple - once the user logs in, the server gives a token, and that token is used for every request after that.
How the Flow Works
Here’s the flow I implemented:
User enters username and password
Backend verifies the credentials
Backend generates a token
Vue stores the token in the browser
Every API call includes that token in the header
If the token is valid, the request is allowed. Otherwise, it’s rejected.
⚙️ Backend Changes (Spring Boot)
On the backend side, I didn’t build everything from scratch. I focused on three key parts:
1). Generating the token
After a successful login, I generate a token that contains the username and an expiration time. This token is signed using a secret key.
String token = Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 3600000))
.signWith(SignatureAlgorithm.HS256, "secret")
.compact();
2). Validating requests
For every request (except login), I check:
Does it have a token?
Is the token valid?
If both conditions pass, the request continues. Otherwise, it’s blocked.
3). Securing endpoints
I configured security so that:
/login is public
Everything else requires authentication
🌐 Frontend Changes (Vue)
On the Vue side, the implementation was pretty straightforward.
Storing the token after login:
axios.post("/login", credentials)
.then(res => {
localStorage.setItem("token", res.data);
});
Sending the token automatically
Instead of adding the token manually every time, I used an interceptor:
axios.interceptors.request.use(config => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = \`Bearer ${token}\`;
}
return config;
});
This way, every request includes the token without repeating code.
🔒 Protecting Frontend Routes
I also added route protection so users can’t access certain pages without logging in.
If there’s no token, the user is redirected back to the login page.
⚠️ Things I Learned Along the Way
A few things that tripped me up:
Hardcoding the secret key is fine for testing, but not for production
Token expiration is important—without it, users stay logged in forever
Storing tokens in localStorage is simple, but has security trade-offs
✅ Final Result
After putting this together:
Users must log in before accessing Apis
Unauthorized requests are blocked
The frontend automatically handles authentication
It’s a big step toward making the app production-ready.
🚀 What I’ll Cover Next
Now that authentication is working, the next step is to actually use it in a real application.
In the next post, I’ll build a complete CRUD app with protected APIs using this setup.
💬 Closing Thoughts
Adding authentication changed how the whole app behaves. It’s no longer just a frontend calling an API—it’s a system with controlled access.
If you’re building something beyond a demo project, this is a must-have.




