Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách quản lý phiên trong ứng dụng Next.js bằng Upstash Redis bằng cách tìm hiểu ý nghĩa của “phiên” trong ứng dụng web, lý do Redis là lựa chọn phù hợp để quản lý phiên, cách thiết lập cơ sở dữ liệu Upstash Redis và cuối cùng là cách tích hợp cơ sở dữ liệu đó vào ứng dụng Next.js.
Phiên là gì?
Trong ứng dụng web, “phiên” là một cơ chế lưu trữ tạm thời phía máy chủ dùng để duy trì trạng thái tương tác của người dùng với ứng dụng qua nhiều yêu cầu HTTP trong một khoảng thời gian nhất định.
Vì HTTP là giao thức không trạng thái, nghĩa là mỗi yêu cầu đều độc lập và không "ghi nhớ" các tương tác trước đó nên phiên cho phép máy chủ theo dõi và lưu trữ dữ liệu cụ thể của người dùng như trạng thái xác thực, tùy chọn hoặc bất kỳ loại hoạt động nào của người dùng trong thời gian họ ở trên trang web.
Phiên thường hoạt động bằng cách lưu trữ một ID phiên duy nhất ở phía máy khách, thường là trong cookie. Máy chủ sử dụng ID này để truy xuất dữ liệu liên quan đến phiên người dùng từ bộ lưu trữ phiên, như Redis trong blog này, mỗi khi người dùng tương tác với trang web.
Phiên trong ứng dụng web là một cách tuyệt vời để xử lý các tương tác của người dùng và quản lý trạng thái sau:
- Xác thực người dùng :Phiên giúp xác thực người dùng và ghi nhớ trạng thái đăng nhập của họ trên các trang hoặc thậm chí sau khi làm mới.
- Cá nhân hóa :Phiên cho phép máy chủ lưu trữ và truy xuất dữ liệu như tùy chọn người dùng, trạng thái xác thực, v.v.
- Bảo mật :Quản lý phiên thích hợp có thể tăng cường bảo mật ứng dụng, chẳng hạn như bảo vệ chống lại CSRF và đảm bảo người dùng trái phép không truy cập vào các khu vực bị hạn chế.
Tại sao phải sử dụng Redis để quản lý phiên?
Tại sao không :)
Có nhiều lý do để sử dụng Redis làm kho lưu trữ phiên để quản lý phiên. Dưới đây là một số lợi thế phát sinh từ cấu trúc của Redis:
-
Cấu trúc dữ liệu :Redis là kho lưu trữ khóa-giá trị trong bộ nhớ. Các cặp khóa-giá trị có thể được lưu trữ dưới dạng băm, trong đó hàm băm là loại bản ghi được cấu trúc dưới dạng tập hợp các cặp giá trị trường. Cấu trúc này hoàn toàn phù hợp với kiểu dữ liệu quản lý phiên để duy trì tất cả dữ liệu phiên, chẳng hạn như tên người dùng, tùy chọn người dùng, v.v. ở định dạng khóa-giá trị dưới dạng hàm băm cho mỗi phiên người dùng.
-
Dữ liệu hết hạn :Redis có chức năng tích hợp để xóa dữ liệu đã hết hạn. Điều này giúp các ứng dụng web duy trì giới hạn thời gian cho các phiên của người dùng.
-
Độ trễ thấp :Do tính chất “trong bộ nhớ”, Redis cực kỳ nhanh. Đó là lý do tại sao nó thường được sử dụng cho phiên người dùng và dữ liệu bộ nhớ đệm.
-
Khả năng mở rộng :Redis được xây dựng để xử lý khối lượng dữ liệu lớn và lưu lượng truy cập thông lượng cao.
Ngoài ra, chúng ta có thể so sánh Redis một cách đơn giản với một trong những cách phổ biến nhất để lưu trữ dữ liệu phiên người dùng, cookie phía máy khách, để quyết định cách chúng ta muốn tuân theo trong các ứng dụng web của mình. Một số ưu điểm của Redis khi lưu trữ phiên so với cookie phía máy khách:
-
Ít bị người dùng giả mạo hơn :Cookie được hiển thị cho người dùng và người dùng có thể thao tác được. Redis cho phép chúng tôi bảo vệ dữ liệu người dùng khỏi bị người dùng thao túng.
-
Ít dữ liệu được truyền giữa máy khách và máy chủ: Vì chúng tôi lưu trữ tất cả thông tin phiên trong Redis nên chúng tôi không cần lưu trữ bất kỳ thứ gì trong máy khách.
-
Chỉ lưu trữ “SessionId” trong máy khách: Nếu sử dụng Redis, chúng ta chỉ cần lấy sessionId cho mỗi yêu cầu để biết yêu cầu này đang ở phiên nào.
Tạo cơ sở dữ liệu Upstash Redis
Trước khi bắt đầu thiết lập Upstash Redis, trước tiên chúng ta nên hiểu những ưu điểm của Upstash Redis. Sẽ chẳng có ý nghĩa gì nếu sử dụng các công cụ mà chúng ta sắp sử dụng mà không hiểu tại sao nên sử dụng chúng, phải không?
Hãy cùng xem những lợi ích chính của việc sử dụng Upstash Redis:
-
Không có máy chủ: Upstash Redis là cơ sở dữ liệu không có máy chủ. Bạn không cần phải duy trì cơ sở hạ tầng, lo lắng về việc mở rộng quy mô cơ sở dữ liệu hoặc bất kỳ cấu hình cấp thấp nào khác. Bạn chỉ cần tạo cơ sở dữ liệu và sử dụng nó.
-
Phân phối dữ liệu toàn cầu: Upstash cho phép bạn triển khai phiên bản Redis ở những khu vực gần với người dùng của bạn, giúp giảm độ trễ hơn nữa. Điều này đặc biệt có lợi cho các ứng dụng được phân phối trên toàn cầu, đảm bảo rằng phiên lưu trữ nhanh và đáp ứng bất kể vị trí của người dùng.
-
Thanh toán khi bạn sử dụng: Không có giá vào cửa. Bạn chỉ trả tiền cho những gì bạn sử dụng. Bạn có thể xem chi tiết về giá.
Được rồi, nếu không còn câu hỏi nào về lý do sử dụng Upstash Redis để quản lý phiên, chúng ta có thể tạo cơ sở dữ liệu Upstash Redis.
Chúng tôi sẽ tạo cơ sở dữ liệu Redis thông qua bảng điều khiển Upstash.
Hãy tạo cơ sở dữ liệu Redis bằng cách nhấp vào nút “Tạo cơ sở dữ liệu”. Hướng dẫn này sẽ một lần nữa cho thấy việc tạo cơ sở dữ liệu Upstash Redis dễ dàng và nhanh chóng như thế nào.
Trong phương thức xuất hiện, chúng tôi sẽ chọn tên cho cơ sở dữ liệu của mình và chọn vùng cho nó. Tốt hơn hết bạn nên chọn cùng khu vực với dịch vụ của mình.
Sau khi nhấp vào nút tiếp theo, chúng tôi sẽ chọn gói giá. Thanh toán theo nhu cầu sử dụng với giới hạn ngân sách tối đa là điều tôi thích nhất!
Bây giờ, cơ sở dữ liệu Redis của chúng tôi đã sẵn sàng. Chúng ta có thể thấy điểm cuối cơ sở dữ liệu, mật khẩu để kết nối với cơ sở dữ liệu và cổng của nó trên bảng điều khiển Redis. Chúng tôi sẽ cần thông tin này khi muốn kết nối với cơ sở dữ liệu từ ứng dụng web.

Thế thôi!
Sử dụng Upstash Redis trong ứng dụng Nextjs
Hãy xem Redis sẽ hoạt động như thế nào trong cơ sở hạ tầng ứng dụng web:
-
Trước tiên, chúng tôi nhận được yêu cầu từ trình duyệt máy khách mà không có bất kỳ sessionId nào.
-
Vì không có sessionId trong yêu cầu nên chúng tôi tạo một sessionId và tạo hàm băm trong Redis.
-
Trả về sessionId dưới dạng cookie trong phản hồi của máy khách.
-
Khi nhận được yêu cầu HTTP mới với sessionId, chúng tôi sẽ truy xuất dữ liệu phiên cần thiết từ Redis và sử dụng dữ liệu đó khi phản hồi máy khách.
Đây là sơ đồ trình tự của dịch vụ và kết nối của nó với Redis để trực quan hóa quy trình tốt hơn:

Nếu mọi thứ đều ổn, chúng ta có thể tạo ứng dụng Nextjs bằng cách chạy lệnh sau trong thiết bị đầu cuối trừ khi bạn có ứng dụng Nextjs.
npx create-next-app@latest <project-name>
Bây giờ chúng ta cần cài đặt Upstash Redis Typescript SDK.
cd <project-name>
npm install @upstash/redis
Sau khi cài đặt phần phụ thuộc bắt buộc, giờ đây chúng tôi có thể tạo giao diện để quản lý ID phiên trong cookie của trình duyệt của người dùng và tương tác với Upstash Redis, bộ lưu trữ phiên của ứng dụng của chúng tôi.
Chúng ta sẽ triển khai giao diện này trong /app/lib/sessionManager.tsx tập tin.
import { Redis } from '@upstash/redis'
import { cookies } from 'next/headers'
export const redis = new Redis({
url: '<UPSTASH-REDIS-URL>',
token: 'UPSTASH-REDIS-TOKEN',
})
type SessionId = string;
type Key = 'userName' | 'sessionStatus'; // other keys of the session data can be added.
export async function getSessionId(): SessionId | undefined {
const cookieStore = await cookies();
return cookieStore.get("session-id")?.value;
}
async function setSessionId(sessionId: SessionId): void {
const cookieStore = await cookies();
cookieStore.set("session-id", sessionId);
}
export async function getSessionIdAndCreateIfMissing() {
const sessionId = await getSessionId();
if (!sessionId) {
const newSessionId = crypto.randomUUID();
await setSessionId(newSessionId);
return newSessionId;
}
return sessionId;
}
export async function get(key: Key, username: string = "") {
const sessionId = await getSessionId();
if (!sessionId) {
return null;
}
return await redis.hget(`session-${username}-${sessionId}`, key);
}
export async function getAll(username: string = "") {
const sessionId = await getSessionId();
if (!sessionId) {
return null;
}
return await redis.hgetall(`session-${username}-${sessionId}`);
}
export async function set(key: Key, value: string, username: string = "") {
const sessionId = await getSessionIdAndCreateIfMissing();
await redis.hset(`session-${username}-${sessionId}`, { [key]: value });
return redis.expire(`session-${username}-${sessionId}`, 900);
} Hãy cùng xem xét các chức năng này.
-
getSessionId :Chúng tôi sẽ lưu trữ ID phiên trong cookie của trình duyệt của người dùng. Chức năng này là lấy ID phiên từ cookie trình duyệt được gửi tới API bên trong lệnh gọi HTTP.
-
setSessionId :Hàm này đặt cookie ID phiên thành tham số ID phiên đã cho.
-
getSessionIdAndCreateIfMissing :Hàm này gọi
getSessionIdđể lấy ID phiên hiện có từ cookie và đặt UUID ngẫu nhiên mới làm ID phiên mới trừ khi đã có ID phiên trong trình duyệt của người dùng. Chức năng này cũng thêm ID phiên mới vào cookie để gửi lại trình duyệt. -
getSessionData :Chúng ta sẽ gọi hàm này để lấy dữ liệu phiên từ Redis. Nó sẽ lấy dữ liệu phiên của khóa đã cho từ Upstash Redis và trả lại.
-
getAllSessionData :Hàm này lấy tất cả dữ liệu phiên. Nó nhận tất cả các cặp khóa-giá trị của hàm băm phiên từ Upstash Redis.
-
setSessionData :Chúng ta sẽ đặt các cặp khóa-giá trị của phiên đã cho trong hàm này.
Vì tiện ích này có chức năng quản lý ID phiên và lưu trữ phiên thông qua Upstash Redis nên giờ đây chúng tôi có thể triển khai API sử dụng các chức năng này.
API sẽ rất đơn giản. Nó sẽ nhận được tên người dùng từ đường dẫn. Khi nhận được yêu cầu, trước tiên nó sẽ kiểm tra xem ID phiên có tồn tại trong cookie hay không. Nếu không có ID phiên trong cookie, nó sẽ tạo ID mới và đặt ID đó vào cookie trong phản hồi. Nếu ID phiên tồn tại, nó sẽ kiểm tra xem có khóa nào trong Upstash Redis trong hàm băm đại diện cho phiên hay không. Nếu không có, nó sẽ tạo các cặp khóa-giá trị trong hàm băm đó.
Hãy viết mã!
API sẽ được tạo bằng cách sử dụng bộ định tuyến ứng dụng của Nextjs.
Chúng ta nên tạo một tệp dưới app/api/user/ [tên người dùng]named tuyến đường.tsx`.
import * as sessionStore from '../../lib/session'
export async function GET(request: Request,{ params }: { params: Promise<{ user: string }> }){
const userName = (await params).user;
const sessionId = await sessionStore.getSessionIdAndCreateIfMissing();
const sessionStatus = await sessionStore.get('sessionStatus', userName);
if(sessionStatus == null) {
console.log('There is no active session.');
await sessionStore.set('sessionStatus', 'ACTIVE', userName);
}
return Response.json({ userName: userName, sessionId: sessionId });
}
Tệp lộ trình này sẽ cho phép Nextjs giải quyết yêu cầu được gửi tới <URL>:3000/api/user/<username> tới các phương thức HTTP được xác định bên trong chính nó.
Bây giờ chúng ta sẽ thấy nó hoạt động. Hãy chạy ứng dụng Nextjs bằng cách đi tới thư mục gốc từ thiết bị đầu cuối và chạy lệnh sau:
npm run dev
Bây giờ, chúng ta có thể mở điểm cuối API, http://localhost:3000/api/user/noah trên một trình duyệt. Khi mở nó, bạn sẽ thấy tên người dùng và ID phiên được trả về:
{"userName":"noah","sessionId":"804814dc-10fc-4b0a-a4c1-321f4b54d399"}
Nếu nhấp chuột phải và kiểm tra, bạn sẽ thấy id phiên được đặt trong cookie bằng cách đi tới tab “Ứng dụng”.

Chúng tôi cũng có thể kiểm tra Upstash Redis xem phiên có được tạo trong cơ sở dữ liệu hay không. Để kiểm tra, chúng ta nên quay lại bảng điều khiển Upstash Redis, mở cơ sở dữ liệu Redis và mở Data Browser tab.
Data Browser tab sẽ hiển thị dữ liệu phiên như hiển thị bên dưới.

Kết luận
Quản lý phiên trong ứng dụng Next.js bằng Upstash Redis cung cấp giải pháp hiệu quả và có thể mở rộng. Trong bài đăng trên blog này, chúng tôi đã tạo một ứng dụng Nextjs và tích hợp nó với Upstash Redis để sử dụng nó làm bộ lưu trữ quản lý phiên.
Bằng cách thiết lập cơ sở dữ liệu Redis và tích hợp nó một cách liền mạch với Next.js, bạn có thể xử lý việc lưu trữ phiên một cách hiệu quả mà không gặp phải những rắc rối phía máy chủ truyền thống. Cách tiếp cận này lý tưởng cho các nhà phát triển đang tìm kiếm hiệu suất và sự đơn giản trong quản lý phiên.
Hy vọng rằng hướng dẫn này đã cung cấp một lộ trình rõ ràng để triển khai Upstash Redis như một kho phiên đáng tin cậy trong các ứng dụng Next.js của bạn.