【问题标题】:Updating/mutating a session with next-auth and tRPC使用 next-auth 和 tRPC 更新/改变会话
【发布时间】:2022-12-04 11:59:19
【问题描述】:

我正在构建一个多租户 NextJS 应用程序,它使用 next-auth 进行帐户身份验证,使用 tRPC 进行 API,使用 postgresql 进行数据存储。

我正在尝试找到一种方法来根据某些客户端交互动态更新/设置/改变会话值

我采用的方法类似于this article中描述的方法:

  • User被授权通过Membership访问Organization
  • 一个User可能有一个Membership到>1个Organization
  • User 可以更改他们通过某些客户端 UI“登录”到的 Organization

当用户进行身份验证时,我想:

  • session.user.orgId 设置为某个 orgId(如果它们属于某个组织)

当用户更改他们通过某些客户端 UI 访问的组织时,我想:

  • 更新session.user.orgId = newOrgId(当然,在这样做之前验证他们有适当的权限)。

我在网上搜索了更新/改变会话值的方法,据我所知,只有使用 next-auth 的 callbacks 才有可能:

...
  callbacks: {
    async session({ session, user, token }) {
      // we can modify session here, i.e `session.orgId = 'blah'`
      // or look up a value in the db and attach it here.
      return session
    },
...
}

但是,在身份验证流程之外,没有明确的方法从客户端触发此更新。即,如果用户在某些 UI 中单击以更改其组织,我如何验证更改并更新会话值,而不需要用户重新进行身份验证?

【问题讨论】:

标签: next.js next-auth trpc.io


【解决方案1】:

侵入 NextAuth 的PrismaAdapter。我的看起来像这样:

文件:[...nextauth].ts

import NextAuth, { Awaitable, type NextAuthOptions } from "next-auth";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import type { AdapterSession, AdapterUser } from "next-auth/adapters";
import { prisma } from "../../../server/db/client";
import { MembershipRole } from "@prisma/client";

...

const adapter = PrismaAdapter(prisma);
adapter.createSession = (session: {
  sessionToken: string;
  userId: string;
  expires: Date;
}): Awaitable<AdapterSession> => {
  return prisma.user
    .findUniqueOrThrow({
      where: {
        id: session.userId,
      },
      select: {
        memberships: {
          where: {
            isActiveOrg: true,
          },
          select: {
            role: true,
            organization: true,
          },
        },
      },
    })
    .then((userWithOrg) => {
      const membership = userWithOrg.memberships[0];
      const orgId = membership?.organization.id;

      return prisma.session.create({
        data: {
          expires: session.expires,
          sessionToken: session.sessionToken,
          user: {
            connect: { id: session.userId },
          },
          organization: {
            connect: {
              id: orgId,
            },
          },
          role: membership?.role as MembershipRole,
        },
      });
    });
};

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2022-12-25
    • 2021-08-17
    • 2021-12-04
    • 2022-12-11
    • 2021-10-26
    • 2021-10-15
    • 2022-09-30
    • 2022-01-07
    相关资源
    最近更新 更多