# How to Implement Frontend-Backend API Integration in the Mall Project

> Learn how to implement frontend-backend API integration in the Mall project using JWT authentication. Securely store and attach tokens for seamless communication.

- Repository: [macro/mall](https://github.com/macrozheng/mall)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Implement frontend-backend API integration in the Mall project by authenticating via JWT tokens from `/sso/login` or `/admin/login`, storing the token, and attaching it to subsequent requests in the `Authorization` header using the format `Bearer <token>`.**

The **macrozheng/mall** project is a Spring Boot-based microservice system that exposes business operations through RESTful HTTP endpoints. To implement frontend-backend API integration, client applications must handle JWT-based authentication, parse the standardized `CommonResult` response wrapper, and communicate with controllers located in the `mall-portal` and `mall-admin` modules according to the source code implementation.

## Authentication Flow and JWT Implementation

The Mall backend uses **JWT (JSON Web Tokens)** as its sole authentication mechanism. The flow begins when the frontend submits credentials to the authentication endpoints and subsequently includes the received token in every protected request.

### Login and Token Generation

The portal module exposes the login endpoint in [`mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java). When a user submits their `username` and `password`, the controller delegates to the service layer, which generates a JWT using `JwtTokenUtil`.

```java
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public CommonResult login(@RequestParam String username,
                         @RequestParam String password) {
     String token = memberService.login(username, password);
     // Returns CommonResult with token and tokenHead
}

```

The backend returns a standardized JSON response containing the token data:

```json
{
  "code": 200,
  "message": "Operation succeeded",
  "data": {
    "token": "<jwt-string>",
    "tokenHead": "Bearer "
  }
}

```

### Token Validation on Requests

For every subsequent API call, the frontend must include the header `Authorization: Bearer <jwt-string>`. The `JwtAuthenticationTokenFilter` class in [`mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java`](https://github.com/macrozheng/mall/blob/main/mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java) intercepts these requests and validates the token.

```java
String authHeader = request.getHeader(jwtProperties.getHeader());
if (authHeader != null && authHeader.startsWith(jwtProperties.getTokenHead())) {
    String authToken = authHeader.substring(jwtProperties.getTokenHead().length());
    // Validation logic proceeds
}

```

### Token Refresh

To maintain sessions without forcing re-login, call `/sso/refreshToken` (portal) or `/admin/refreshToken` (admin) with the current valid token in the header. The endpoint returns a new JWT with extended expiration.

## Request and Response Standards

All API responses in the Mall project follow a uniform structure defined by `CommonResult<T>` located in [`mall-common/src/main/java/com/macro/mall/common/api/CommonResult.java`](https://github.com/macrozheng/mall/blob/main/mall-common/src/main/java/com/macro/mall/common/api/CommonResult.java).

### CommonResult Structure

The wrapper ensures consistent error handling and data access across all endpoints:

```java
public class CommonResult<T> {
    private long code;      // 200 indicates success
    private String message; // Human-readable status
    private T data;         // Payload object
}

```

### Pagination with CommonPage

List endpoints return paginated data using `CommonPage<T>` nested within `CommonResult`. The data object includes `list`, `pageNum`, `pageSize`, `total`, and `totalPage` fields.

```json
{
  "code": 200,
  "message": "Operation succeeded",
  "data": {
    "list": [ { "id": 1, "name": "Product Name" } ],
    "pageNum": 1,
    "pageSize": 5,
    "total": 42,
    "totalPage": 9
  }
}

```

## Frontend Integration Patterns

Implement the integration using any HTTP client library. The following examples use **axios** in a JavaScript frontend.

### Configuring Axios with JWT Interceptors

Create an axios instance that automatically injects the stored JWT into request headers. Store both the `token` and `tokenHead` (typically `"Bearer "`) in localStorage after login.

```javascript
import axios from 'axios'

const api = axios.create({
  baseURL: process.env.VUE_APP_API_BASE || 'http://localhost:8080',
  timeout: 10000
})

api.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  const tokenHead = localStorage.getItem('tokenHead') || 'Bearer '
  if (token) {
    config.headers['Authorization'] = tokenHead + token
  }
  return config
})

export default api

```

### Handling Login and Token Storage

Post credentials to `/sso/login` for portal users or `/admin/login` for administrators. Extract and persist the token components upon successful authentication.

```javascript
export function login(username, password) {
  return api.post('/sso/login', null, {
    params: { username, password }
  }).then(res => {
    if (res.data.code === 200) {
      const { token, tokenHead } = res.data.data
      localStorage.setItem('token', token)
      localStorage.setItem('tokenHead', tokenHead)
    }
    return res.data
  })
}

```

### Making Authenticated API Calls

Protected endpoints automatically receive the JWT header through the interceptor. Public endpoints (like product listings) work without authentication.

```javascript
// Protected endpoint - requires valid JWT
export function getMemberInfo() {
  return api.get('/sso/info')
    .then(res => res.data)
}

// Public endpoint - no token required
export function listProducts(params) {
  return api.get('/product/list', { params })
    .then(res => res.data) // Returns CommonResult<CommonPage<Product>>
}

```

### Implementing Token Refresh

Schedule periodic token refreshes to prevent session expiration during active use.

```javascript
export function refreshToken() {
  return api.get('/sso/refreshToken')
    .then(res => {
      if (res.data.code === 200) {
        const { token, tokenHead } = res.data.data
        localStorage.setItem('token', token)
        localStorage.setItem('tokenHead', tokenHead)
      }
      return res.data
    })
}

```

## API Documentation with Swagger

The Mall backend provides interactive API documentation via Swagger UI. The configuration in [`mall-portal/src/main/java/com/macro/mall/portal/config/SwaggerConfig.java`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/config/SwaggerConfig.java) enables security header support, allowing you to test authenticated endpoints directly in the browser.

Access the documentation at:

- **Portal APIs**: `http://localhost:8080/swagger-ui.html?url=/v2/api-docs&group=mall-portal`
- **Admin APIs**: `http://localhost:8080/swagger-ui.html?url=/v2/api-docs&group=mall-admin`

Swagger displays all available endpoints, required parameters, and the exact `Authorization` header format required for each controller method.

## Key Source Files for Integration

Understanding these specific source files ensures proper implementation of the integration patterns:

- **[`mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java)** – Handles member login and token generation.
- **`mall-admin/src/main/java/com/macro/mall/controller/*Controller.java`** – Contains administrative API endpoints.
- **[`mall-security/src/main/java/com/macro/mall/security/util/JwtTokenUtil.java`](https://github.com/macrozheng/mall/blob/main/mall-security/src/main/java/com/macro/mall/security/util/JwtTokenUtil.java)** – Utility class for creating and parsing JWT tokens.
- **[`mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java`](https://github.com/macrozheng/mall/blob/main/mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java)** – Spring Security filter that validates tokens on incoming requests.
- **[`mall-common/src/main/java/com/macro/mall/common/api/CommonResult.java`](https://github.com/macrozheng/mall/blob/main/mall-common/src/main/java/com/macro/mall/common/api/CommonResult.java)** – Standard response wrapper used by all controllers.
- **[`mall-portal/src/main/resources/application.yml`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/resources/application.yml)** – Configuration file containing JWT secret, token header name, and ignored URL patterns under `secure.ignored.urls`.

## Summary

- **JWT Authentication** is mandatory for protected endpoints; obtain tokens via `/sso/login` or `/admin/login` and include them in the `Authorization: Bearer <token>` header.
- **CommonResult<T>** provides a consistent response structure with `code`, `message`, and `data` fields across all API interactions.
- **Axios interceptors** streamline token management by automatically injecting the JWT into request headers from localStorage.
- **Swagger UI** offers live documentation and testing capabilities for all backend endpoints at the configured URLs.
- **Token refresh** endpoints (`/sso/refreshToken`) allow seamless session extension without requiring user credentials again.

## Frequently Asked Questions

### How do I handle JWT token expiration in the frontend?

Detect HTTP 401 Unauthorized responses in your API error handler, then automatically call the `/sso/refreshToken` endpoint with the current token to obtain a new one. If the refresh fails or returns 401, redirect the user to the login page to re-authenticate.

### What is the correct format for the Authorization header?

The header must match the pattern defined in [`application.yml`](https://github.com/macrozheng/mall/blob/main/application.yml), which defaults to `Bearer <token>`. The `tokenHead` value (including the trailing space) is returned during login alongside the token itself, ensuring the frontend constructs the header exactly as the `JwtAuthenticationTokenFilter` expects.

### How does the backend validate incoming JWT tokens?

The `JwtAuthenticationTokenFilter` extracts the token from the `Authorization` header, removes the `tokenHead` prefix, and validates the signature and expiration using `JwtTokenUtil`. Valid tokens trigger the loading of user details via `loadUserByUsername`, establishing the security context for the request.

### Where can I find the complete list of available API endpoints?

Access the Swagger UI at `http://localhost:8080/swagger-ui.html` after starting the backend services. The interface documented in [`SwaggerConfig.java`](https://github.com/macrozheng/mall/blob/main/SwaggerConfig.java) provides a complete inventory of controllers, their HTTP methods, request parameters, and authentication requirements for both portal and admin modules.