b. JWT
The first step in building the security layer is understanding JSON Web Tokens (JWT) and creating the auth interface module that defines the API contract for authentication.
1. JSON Web Token
JWT is a compact, URL-safe way to represent claims between two parties. It is the standard used by the platform to carry the authenticated user's identity across services without storing server-side session state — making it naturally compatible with horizontal scalability.
A JWT consists of three Base64Url-encoded parts separated by dots.
Example JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJJbnNwZXIiLCJpYXQiOjE3MDMwMDgzMzgsImV4cCI6MjAxODU0MTEz
OCwiYXVkIjoid3d3Lmluc3Blci5lZHUuYnIiLCJzdWIiOiJodW1iZXJ0b3JzQGluc3Blci5lZHUuYnIiLCJHaXZlbk5hbWUiOiJId
W1iZXJ0byIsIlN1cm5hbWUiOiJTYW5kbWFubiIsIkVtYWlsIjoiaHVtYmVydG9yc0BpbnNwZXIuZWR1LmJyIiwiUm9sZSI6IlByb2
Zlc3NvciJ9.SsGdvR5GbYWTRbxY7IGxHt1vSxhkpRueBJWsi0lrPhJVCICp119QjU8F3QvHW0yF5tw-HhQ9RVh0l89t4M0LNw
The header typically consists of two parts: the type of the token (JWT) and the signing algorithm being used, such as HMAC SHA256 or RSA.
{
"iss": "Insper",
"iat": 1703008338,
"exp": 2018541138,
"aud": "www.insper.edu.br",
"sub": "humbertors@insper.edu.br",
"GivenName": "Humberto",
"Surname": "Sandmann",
"Email": "humbertors@insper.edu.br",
"Role": "Professor"
}
The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims. Registered claims are a set of predefined claims which are not mandatory but recommended, to provide a set of useful, interoperable claims. Some examples are iss (issuer), exp (expiration time), sub (subject), and aud (audience). Public claims can be defined at will by those using JWTs. To avoid collisions they should be defined in the IANA JSON Web Token Registry or be defined as a URI that contains a collision resistant namespace. Private claims are the custom claims created to share information between parties that agree on using them and are neither registered nor public claims.
Secret Key
The secret key used to sign the JWT must be kept confidential. Anyone with access to it can forge tokens. Store it as an environment variable — never hardcode it in source code.
The key claims used in this platform are:
| Claim | Field | Description |
|---|---|---|
jti | id | The account's unique identifier |
sub | subject | The account's name |
iss | issuer | The issuing platform |
nbf | notBefore | Token becomes valid at this timestamp |
exp | expiration | Token expires at this timestamp |
After a successful login, the server generates a JWT, sets it in an HttpOnly cookie, and returns it to the browser. For every subsequent request, the browser sends the cookie automatically — the Gateway reads it and resolves the identity without asking the user to log in again.
sequenceDiagram
autonumber
actor User
User->>+Auth Service: login (email + password)
Auth Service->>Auth Service: validates credentials and generates JWT
Auth Service->>-User: Set-Cookie: __store_jwt_token=<jwt>
User->>User: browser stores the cookie
User->>Gateway: subsequent requests carry the cookie automatically 2. The auth Interface Module
The auth module follows the same pattern as the account module: it is a library (not a runnable application) that defines the API contract and DTOs shared between the auth-service and any other microservice that needs to call the auth endpoints via Feign.
2.1 Repository
Create a new git repository for the auth interface and add it as a submodule:
2.2 Code
Use Spring Initializr to generate a Maven project with the following settings:
- Group:
store - Artifact:
auth - Package name:
store.auth - Packaging: Jar
- Java: 25
Dependencies to add:
- Lombok — reduces boilerplate with compile-time annotation processing
- OpenFeign — declarative HTTP client for inter-service calls
Delete AuthApplication.java, src/test/, and src/main/resources/ — this module is a library, not a runnable service.
The resulting structure is:
📁 api/
└── 📁 auth/
├── 📁 src/
│ └── 📁 main/
│ └── 📁 java/
│ └── 📁 store/
│ └── 📁 auth/
│ ├── AuthController.java
│ ├── LoginIn.java
│ ├── RegisterIn.java
│ └── TokenOut.java
└── pom.xml
Source
The /auth/solve endpoint
solveToken is an internal endpoint called by the Gateway only. It receives a raw JWT string and returns the corresponding idAccount. It is never exposed directly to the browser.
2.3 Install
Install the interface to the local Maven repository so auth-service can depend on it:
Done! The auth interface is ready. In the next section we will implement auth-service, including the JwtService that signs and validates tokens, and AuthService that orchestrates login and registration.