Giới thiệu
Strapi v5 cung cấp cơ chế mở rộng mạnh mẽ thông qua middleware và controller tùy chỉnh. Khi xây dựng các API nội bộ hoặc cho các ứng dụng di động, việc bảo vệ endpoint bằng JSON Web Token (JWT) là một yêu cầu phổ biến. Bài viết này sẽ hướng dẫn chi tiết cách tạo middleware xác thực JWT, tích hợp vào route và xây dựng controller trả về dữ liệu bảo vệ.
Tạo middleware xác thực JWT
1. Cài đặt thư viện jsonwebtoken
Trước tiên, cần cài đặt gói jsonwebtoken để tạo và xác thực token.
npm install jsonwebtoken --save
2. Tạo file middleware
Trong thư mục src/middlewares (hoặc ./src/middlewares tùy cấu trúc dự án), tạo file jwt-auth.js và viết logic kiểm tra token.
const jwt = require('jsonwebtoken');
module.exports = (config, { strapi }) => {
return async (ctx, next) => {
const authHeader = ctx.request.headers['authorization'];
if (!authHeader) {
ctx.throw(401, 'Missing Authorization header');
}
const token = authHeader.split(' ')[1]; // Expected format: Bearer <token>
if (!token) {
ctx.throw(401, 'Token not provided');
}
try {
const payload = jwt.verify(token, process.env.JWT_SECRET);
// Gắn thông tin người dùng vào ctx.state để các controller có thể dùng
ctx.state.user = payload;
} catch (err) {
ctx.throw(401, 'Invalid or expired token');
}
await next();
};
};Trong đoạn code trên, process.env.JWT_SECRET là khóa bí mật được lưu trong biến môi trường, giúp tăng tính bảo mật.
Đăng ký middleware trong Strapi
Để Strapi nhận biết middleware mới, mở file config/middlewares.js (hoặc ./src/config/middlewares.js) và thêm cấu hình sau:
module.exports = [
'strapi::errors',
'strapi::security',
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::session',
// Middleware tùy chỉnh
{
name: 'global::jwt-auth',
config: {},
},
];Với cấu hình global::jwt-auth, middleware sẽ được áp dụng cho mọi route. Nếu muốn chỉ áp dụng cho một số route, có thể khai báo trong src/api/[api-name]/routes/*.js bằng cách thêm config: { middlewares: ['global::jwt-auth'] }.
Tạo controller tùy chỉnh trả về dữ liệu bảo vệ
Giả sử chúng ta muốn xây dựng một endpoint /api/secure-data chỉ trả về dữ liệu khi token hợp lệ. Tạo controller trong src/api/secure-data/controllers/secure-data.js:
module.exports = {
async find(ctx) {
// Dữ liệu người dùng đã được gắn vào ctx.state.user bởi middleware
const user = ctx.state.user;
if (!user) {
ctx.throw(401, 'User not authenticated');
}
// Ví dụ trả về thông tin cơ bản của người dùng
ctx.body = {
message: 'Access granted',
userId: user.id,
email: user.email,
};
},
};Tiếp theo, định nghĩa route trong src/api/secure-data/routes/secure-data.js để liên kết controller và middleware.
module.exports = {
routes: [
{
method: 'GET',
path: '/secure-data',
handler: 'secure-data.find',
config: {
policies: [],
middlewares: ['global::jwt-auth'],
},
},
],
};Kiểm tra API bằng Postman hoặc curl
Đầu tiên, tạo token bằng một endpoint đăng nhập (hoặc dùng jwt.sign trực tiếp). Sau đó, gửi yêu cầu:
curl -H "Authorization: Bearer <your_jwt_token>" http://localhost:1337/api/secure-data
Nếu token hợp lệ, phản hồi sẽ là:
{
"message": "Access granted",
"userId": 12,
"email": "[email protected]"
}Kết luận
Việc triển khai middleware JWT trong Strapi v5 cho phép bạn bảo vệ các endpoint một cách linh hoạt, đồng thời giữ cho logic xác thực tách biệt khỏi controller. Khi cần mở rộng, bạn có thể thêm các policy hoặc role‑based access control dựa trên ctx.state.user. Tham khảo khóa học "Xây dựng Back-End Nodejs bằng Strapi CMS" tại đây để nắm vững toàn bộ quy trình phát triển API-first với Strapi.



.jpg)




