javascript - Opprett T3-app-omdirigering inne i en TRPC-mellomvare hvis brukeren ikke er pålogget


Hvordan kan jeg utløse en omdirigering på serversiden hvis en innlogget bruker ikke har fullført profilsiden sin

const enforceUserIsAuthed = t.middleware(({ ctx, next }) => {
  if (!ctx.session || !ctx.session.user) {
    throw new TRPCError({ code: "UNAUTHORIZED" });
  }

  // redirect to profile page if user has not completed profile


  return next({
    ctx: {
      // infers the `session` as non-nullable
      session: { ...ctx.session, user: ctx.session.user },
    },
  });
});

Svar #1

Dette er for øyeblikket ikke mulig på den måten du beskriver, så vidt jeg vet.

Her er noen alternativer som kan være nyttige:

I getServerSideProps

Dette fungerer bare hvis du vil omdirigere før den første sideinnlastingen. Du kan også lage en wrapper rundt gSSP for å gjøre dette mer DRY hvis du skal bruke det på mange sider.

import { type GetServerSidePropsContext } from "next";
import { getServerAuthSession } from "../server/auth";

export async function getServerSideProps(ctx: GetServerSidePropsContext) {
  const session = await getServerAuthSession(ctx);

  if (!session) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  return {
    props: {},
  };
}

export default function AuthedPage() {
  return <div>Authed</div>;
}

Som en del av en spørring eller mutasjon på klientsiden

Dette er nyttig for en spørring eller mutasjon som bare utføres etter at siden har lastet. Igjen, dette er et veldig enkelt eksempel og kunne vært DRYet, sannsynligvis den enkleste måten ville være å trekke det ut i en tilpasset hook.

import { useRouter } from "next/router";
import { api } from "../utils/api";

export default function AuthedPage() {
  const router = useRouter();

  // `authedHello` is the example Create T3 App "hello" procedure
  // but as a protectedProcedure, ie throws "UNAUTHORIZED" if no session.
  // Replace this with a middleware that throws on whatever condition you need it to.
  const authedHello = api.example.protectedHello.useQuery(
    { text: "world" },
    {
      retry: (_count, err) => {
        // `onError` only runs once React Query stops retrying
        if (err.data?.code === "UNAUTHORIZED") {
          return false;
        }
        return true;
      },
      onError: (err) => {
        if (err.data?.code === "UNAUTHORIZED") {
          void router.push("/");
        }
      },
    }
  );

  return (
    <div>
      <h1>Authed Page</h1>
      <p>{authedHello.data?.greeting}</p>
    </div>
  );
}

Bruke Next.js mellomvare

Dette er lett å bruke på en rekke ruter ved hjelp av matcheren, men det faller litt utenfor T3-konvensjonene.

// pages/middleware.ts
import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "../server/auth";
import type { NextApiRequest, NextApiResponse } from "next";

export async function middleware(req: NextApiRequest, res: NextApiResponse) {
  const session = await getServerSession(req, res, authOptions);
  if (!session?.user) {
    return NextResponse.redirect(new URL("/", req.url));
  }
}

export const config = {
  matcher: ["/protectedPage", "/anotherProtectedPage"],
};

Bruke require i next-auth sin useSession

dette er nyttig hvis du vil beskytte en side, men ikke kan bruke getServerSideProps. Det løser ikke helt ditt spesifikke problem, men kan være nyttig for andre som finner dette. Se: https://next-auth.js.org/getting-started/client#require-session

Relaterte artikler