NextAuth.js
Hvis du vil ha et autentiseringssystem i Next.js-applikasjonen din, er NextAuth.js en utmerket lÞsning for Ä unngÄ kompleksiteten med Ä bygge det selv. Den kommer med en omfattende liste leverandÞrer for raskt Ä legge til OAuth-autentisering og tilbyr adaptere for mange databaser og ORM-er.
KontekstleverandĂžr
I applikasjonens inngangspunkt vil du se at applikasjonen er pakket inn av en SessionProviderâ.
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
Denne kontekstleverandÞren lar applikasjonen din fÄ tilgang til din session
-data fra hvor som helst i applikasjonen din uten Ä mÄtte sende dem som props:
import { useSession } from "next-auth/react";
const User = () => {
const { data: session } = useSession();
if (!session) {
// HÄndter uautentisert state f.eks. ved Ä vise en pÄloggingskomponent
return <SignIn />;
}
return <p>Welcome {session.user.name}!</p>;
};
Henting av session pÄ serversiden
Noen ganger vil du kanskje be om session pĂ„ serveren. For Ă„ gjĂžre dette, prefetchâer du session ved Ă„ bruke getServerAuthSession
-hjelperfunksjonen som create-t3-app
gir, sender den videre til klienten ved Ă„ bruke getServerSideProps
:
import { getServerAuthSession } from "../server/auth";
import type { GetServerSideProps } from "next";
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const session = await getServerAuthSession(ctx);
return {
props: { session },
};
};
const User = () => {
const { data: session } = useSession();
// MERK: `session` vil ikke ha en lastestatus siden den allerede er prefetched pÄ serveren
...
}
Inkluder user.id
i din Session
create-t3-app
er konfigurert til Ă„ bruke session callbackâ i NextAuth.js-konfigurasjonen for Ă„ inkludere bruker-ID i âsessionâ-objektet.
callbacks: {
session({ session, user }) {
if (session.user) {
session.user.id = user.id;
}
return session;
},
},
Dette er kombinert med en typedeklarasjonsfil for Ă„ sikre at user.id
er riktig typet nÄr du fÄr tilgang til session
-objektet. Les mer om "Module Augmentation"
â i NextAuth.js-dokumentasjonen.
import { DefaultSession } from "next-auth";
declare module "next-auth" {
interface Session {
user?: {
id: string;
} & DefaultSession["user"];
}
}
Det samme mĂžnsteret kan brukes til Ă„ legge til flere data til session
-objektet, som f.eks et role
-felt, men skal ikke misbrukes til Ä lagre sensitive data pÄ klienten.
Bruk med tRPC
Hvis du bruker NextAuth.js med tRPC, kan du opprette gjenbrukbare beskyttede prosedyrer med middlewaresâ. Dette lar deg lage prosedyrer som bare er tilgjengelige for autentiserte brukere. create-t3-app
gir deg allerede dette, slik at du enkelt kan fÄ tilgang til session-objektet i autentiserte prosedyrer.
Dette skjer i to trinn:
- FĂ„ tilgang til sesjonen fra request-headerne ved Ă„ bruke funksjonen
getServerSession
â. Fordelen medgetServerSession
sammenlignet medgetSession
er at det er en funksjon pÄ serversiden og medfÞrer ikke unÞdvendige kall.create-t3-app
lager en hjelpefunksjon som abstraherer dette sÊregne API-et, slik at du ikke trenger Ä importere bÄde NextAuth.js-alternativene dine sÄ vel somgetServerSession
-funksjonen hver gang du trenger tilgang til sesssion.
export const getServerAuthSession = (ctx: {
req: GetServerSidePropsContext["req"];
res: GetServerSidePropsContext["res"];
}) => {
return getServerSession(ctx.req, ctx.res, authOptions);
};
Med denne hjelpefunksjonen kan vi hente sesjonen og sende den videre til tRPC-konteksten:
import { getServerAuthSession } from "../auth";
export const createContext = async (opts: CreateNextContextOptions) => {
const { req, res } = opts;
const session = await getServerAuthSession({ req, res });
return await createContextInner({
session,
});
};
- Lag en tRPC-middleware som sjekker om brukeren er autentisert. Vi bruker deretter middlewaren i en
protectedProcedure
. Hvert kall av disse prosedyrene mÄ autentiseres, ellers kastes en feilmelding, som kan hÄndteres av klienten.
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
// inferer `session` som ikke-nullbar
session: { ...ctx.session, user: ctx.session.user },
},
});
}));
Session
-objektet er en minimal representasjon av brukeren og inneholder bare noen fÄ felt. Hvis du bruker protectedProcedures
, har du tilgang til brukerens ID, som kan brukes til Ă„ hente ut mer data fra databasen.
const userRouter = router({
me: protectedProcedure.query(async ({ ctx }) => {
const user = await prisma.user.findUnique({
where: {
id: ctx.session.user.id,
},
});
return user;
}),
});
Bruk med Prisma
Mye fĂžrstegangsoppsettâ kreves for Ă„ bruke NextAuth.js med Prisma. create-t3-app
vil gjĂžre dette for deg, og hvis du velger bĂ„de Prisma og NextAuth.js, fĂ„r du et fullt funksjonelt autentiseringssystem med alle nĂždvendige modeller forhĂ„ndskonfigurert. Vi oppretter applikasjonen din med en forhĂ„ndskonfigurert Discord OAuth-leverandĂžr, som vi valgte siden den er en av de enkleste leverandĂžrene Ă„ komme i gang med â du trenger bare Ă„ legge inn tokens i .env
-filen og du er i gang. Du kan imidlertid enkelt legge til flere leverandĂžrer ved Ă„ fĂžlge NextAuth.js-dokumentasjonenâ. VĂŠr oppmerksom pĂ„ at enkelte leverandĂžrer krever at du legger til flere felt i enkelte modeller. Vi anbefaler Ă„ lese dokumentasjonen for leverandĂžren du planlegger Ă„ bruke for Ă„ sikre at alle obligatoriske felt er til stede.
Legge til nye felt i modellene dine
Hvis du legger til nye felt i noen av modellene User
, Account
, Session
eller VerificationToken
(du trenger sannsynligvis bare Ă„ justere User
-modellen), mĂ„ du huske pĂ„ at Prisma-adapterenâ automatisk legger til felt i disse modellene nĂ„r nye brukere registrerer seg og logger pĂ„. SĂ„ nĂ„r du legger til nye felt i disse modellene, mĂ„ du oppgi standardverdier for dem fordi adapteren ikke vet om disse feltene.
Hvis du for eksempel vil legge til et role
-felt i User
-modellen, mÄ du angi en standardverdi for feltet. Dette oppnÄs ved Ä legge til en @default
-verdi i role
-feltet i User
-modellen:
+ enum Role {
+ USER
+ ADMIN
+ }
model User {
...
+ role Role @default(USER)
}
Bruk med Next.js middleware
Bruk av NextAuth.js med Next.js middleware krever bruk av âJWT session strategyââ for autentisering. Dette er fordi middlewaren bare kan fĂ„ tilgang til session-informasjonskapslene nĂ„r den er en JWT. Som standard er create-t3-app
konfigurert til Ă„ bruke default-databasestrategien, i kombinasjon med Prisma som databaseadapter.
Oppsett av DiscordProvider (standard)
-
Naviger til Applications-delen i Discord Developer Portalâ og klikk pĂ„ âNew Applicationâ
-
Bytt til âOAuth2 => Genereltâ i settings-menyen
- Kopier klient-ID-en og lim den inn i
DISCORD_CLIENT_ID
i.env
. - Under Client Secret, klikk pĂ„ âReset Secretâ og kopier denne strengen til
DISCORD_CLIENT_SECRET
i.env
. VĂŠr forsiktig siden du ikke lenger vil kunne se denne hemmeligheten og tilbakestilling av den vil fĂžre til at den eksisterende hemmeligheten utlĂžper. - Klikk pĂ„ âAdd Redirectâ og lim inn
<app url>/api/auth/callback/discord
(eksempel for utvikling i lokal miljĂž:http://localhost:3000/api/auth/callback/discordâ
) - Lagre endringene dine
- Det er mulig, men ikke anbefalt, Ă„ bruke samme Discord-applikasjon for utvikling og produksjon. Du kan ogsĂ„ vurdere Ă„ Mocke leverandĂžrenâ under utviklingen.
Nyttige Ressurser
Ressurser | Link |
---|---|
NextAuth.js Dokumentasjon | https://next-auth.js.org/â |
NextAuth.js GitHub | https://github.com/nextauthjs/next-authâ |
tRPC Kitchen Sink - med NextAuth | https://kitchen-sink.trpc.io/next-authâ |