casualroom/apps/fenghuo/api/src/trpc/base.ts

72 lines
1.6 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
import { sessionManager } from '../auth/session';
import { UserWithRelations } from '@fenghuo/common/user';
import { extractRequestInfo, RequestInfo } from '../utils/request';
// 定义上下文类型
export interface Context {
user?: UserWithRelations;
requestInfo: RequestInfo;
}
/**
* 创建上下文函数用于tRPC服务器
* @param opts 选项对象,包含请求对象
* @returns 上下文对象
*/
export const createContext = async (opts?: { req?: any }): Promise<Context> => {
// 提取请求信息IP地址、User Agent等
const requestInfo = extractRequestInfo(opts?.req);
// 如果有请求对象,尝试获取用户会话信息
if (opts?.req) {
const session = await sessionManager.getSessionFromRequest(opts.req);
if (session) {
return {
user: session.user,
requestInfo
};
}
}
// 没有有效的认证信息时返回空上下文
return {
user: undefined,
requestInfo
};
};
// 初始化 tRPC
const t = initTRPC.context<Context>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
code: error.code,
},
};
},
});
export const publicProcedure = t.procedure;
export const router = t.router;
/**
* 需要认证的过程 - 确保用户已登录
*/
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
// 检查用户是否已通过认证
if (!ctx.user) {
throw new Error('未授权访问 - 请先登录');
}
return next({
ctx: {
...ctx,
user: ctx.user, // 确保用户存在,用户信息可通过 ctx.user 访问
},
});
});