You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化TypeScript-Next.js Server Actions的会话校验结构

统一处理Server Actions的会话校验方案

问题背景

我有多个Server Actions(比如createProduct、getProductAssets等),目前每个Action在请求时都会先校验用户会话的有效性。我希望只执行一次会话校验,通过后再调用目标函数,请问该如何组织product-actions/index文件的结构?以下是其中一个函数示例:

export async function getProductAssets(productId: string) {
  try {
    const session: Session = await getServerSession(authOptions);
    if (!session.user) {
      return {
        success: false,
        message: 'Unauthorized!',
      };
    }
    // 后续业务逻辑...
  } catch (error) {
    // 错误处理...
  }
}

解决方案:用高阶函数统一封装校验逻辑

把会话校验逻辑抽离成一个通用的包装函数(高阶函数),所有需要校验的Server Actions都通过这个函数包裹,实现一次校验复用。

具体实现结构(product-actions/index.ts)

import { getServerSession } from "next-auth/next";
import { authOptions } from "../auth/[...nextauth]"; // 根据你的项目路径调整
import type { Session } from "next-auth";

// 通用会话校验包装函数
async function withAuth<T extends (...args: any[]) => Promise<any>>(
  handler: (session: Session, ...args: Parameters<T>) => ReturnType<T>
): T {
  return async (...args: Parameters<T>) => {
    try {
      const session = await getServerSession(authOptions);
      // 校验会话有效性
      if (!session?.user) {
        return {
          success: false,
          message: 'Unauthorized!'
        };
      }
      // 校验通过,执行业务逻辑并传入会话信息
      return handler(session, ...args);
    } catch (error) {
      return {
        success: false,
        message: 'Session verification failed'
      };
    }
  } as T;
}

// --- 业务逻辑函数(仅处理核心业务,无需重复写校验)---
async function getProductAssetsHandler(session: Session, productId: string) {
  // 这里写原本的getProductAssets业务逻辑
  // 比如从数据库查询产品资产
  return {
    success: true,
    data: [/* 资产数据示例 */]
  };
}

async function createProductHandler(session: Session, productData: { name: string; price: number }) {
  // 创建产品的核心逻辑,可利用session中的用户信息做权限控制
  return {
    success: true,
    productId: 'prod-123'
  };
}

// --- 导出经过校验包装的Server Actions ---
export const getProductAssets = withAuth(getProductAssetsHandler);
export const createProduct = withAuth(createProductHandler);

优势说明

  • 代码复用:避免在每个Server Action中重复写会话校验代码,减少冗余。
  • 统一维护:后续若要修改校验规则(比如增加角色权限校验),只需修改withAuth函数,无需逐个调整业务Action。
  • 权限传递:业务逻辑函数可直接拿到session,方便做更细粒度的权限控制(比如判断用户是否有权限操作当前产品)。

内容的提问来源于stack exchange,提问作者Fatih Can

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:22:46