如何通过Google Apps Script访问受next-auth保护的tRPC端点?
解决Google Apps Script访问tRPC受保护端点的session验证问题
核心问题原因
Google Apps Script发起的请求是独立的服务器端请求,不会自动携带浏览器端的session cookie,而你的tRPC中间件仅依赖ctx.session(通常来自浏览器请求的cookie解析),所以GAS请求无法通过验证。
解决方案步骤
1. 修改tRPC中间件,支持从请求头读取session标识
调整中间件逻辑,允许从自定义请求头获取session ID,再去Prisma数据库中查询验证,替换原有的仅依赖ctx.session的逻辑:
.middleware(async ({ ctx, req, next }) => { // 从自定义请求头获取session ID(可根据你的实际情况调整头名称) const sessionId = req.headers['x-session-id']; let session; if (sessionId) { // 查询Prisma数据库中的有效session session = await prisma.session.findUnique({ where: { id: sessionId }, // 如果需要关联用户信息,添加include字段 include: { user: true } }); } if (!session) { throw new TRPCError({ code: "UNAUTHORIZED" }); } // 将验证后的session挂载到ctx,供后续路由使用 return next({ ctx: { ...ctx, session } }); })
2. 在Google Apps Script中携带session ID发起请求
先在本地登录你的系统,从浏览器开发者工具中找到有效的session ID(通常存储在cookie中,键名可能是sessionId、connect.sid等),然后在GAS请求中通过请求头传递这个ID:
function callProtectedTRPC() { // 替换为你从浏览器获取的有效session ID const validSessionId = "your-valid-session-id-from-browser"; const trpcEndpoint = "https://your-trpc-server-url.com/trpc"; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", "X-Session-ID": validSessionId }, payload: JSON.stringify({ jsonrpc: "2.0", method: "your.procedure.name", // 替换为你的tRPC procedure名称 params: { input: {} // 替换为procedure需要的输入参数 }, id: 1 }) }; try { const response = UrlFetchApp.fetch(trpcEndpoint, requestOptions); Logger.log("请求结果:" + response.getContentText()); } catch (e) { Logger.log("请求失败:" + e.message); } }
3. 安全与优化建议
- 不要硬编码session ID:使用Google Apps Script的
PropertiesService存储session ID,避免代码泄露。 - 检查session有效期:确保使用的session ID在Prisma数据库中未过期,避免因session失效导致请求失败。
- 可选:改用JWT验证:如果后续想简化流程,可以将session机制替换为JWT,直接在GAS中携带JWT令牌,中间件通过验证JWT签名来授权,无需查询数据库。
内容的提问来源于stack exchange,提问作者Noah -
相关产品推荐
相关产品推荐

