Skip to content

Commit 0a6984c

Browse files
author
Harshit Yadav
committed
feat: added callbacks to middleware, session added, token added, role added in token
1 parent 9948a5d commit 0a6984c

File tree

5 files changed

+177
-3
lines changed

5 files changed

+177
-3
lines changed

README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ export const getUserById = async (id: string) => {
150150

151151
38. Go to see logs `http://localhost:3000/api/auth/providers`
152152

153+
## middlewares and login
154+
153155
39. Create middleware in `middleware.ts` in root directory
154156

155157
- `middleware.ts` file is nextjs specific file
@@ -292,3 +294,125 @@ export default Settings
292294
```
293295

294296
#### Login/Logout completed succesfully
297+
298+
## Callbacks
299+
300+
49. add callbacks in `auth.ts` - to check for tokens
301+
`export const {
302+
handlers: { GET, POST },
303+
auth,
304+
signIn,
305+
signOut,
306+
} = NextAuth({
307+
callbacks: {
308+
async jwt({ token }) {
309+
console.log({ token });
310+
return token;
311+
},
312+
},
313+
adapter: PrismaAdapter(db), // prisma adapter is supported on non edge
314+
session: { strategy: "jwt" },
315+
...authConfig,
316+
});`
317+
318+
50. update callback in `auth.ts` file
319+
320+
```
321+
async session({ token, session }) {
322+
if (token.sub && session.user) {
323+
session.user.id = token.sub;
324+
}
325+
326+
return session;
327+
},
328+
```
329+
330+
51. Update schema in `schema.prisma` file
331+
332+
```
333+
role UserRole @default(USER)
334+
```
335+
336+
52. Close the server
337+
- run command `npx prisma generate` and then `npx prisma migrate reset` and then `npx prisma db push`
338+
- you can check the db status, users would be 0
339+
340+
### Role based authentication is developed with help of middleware and token in callback
341+
342+
### Query is much faste in case of finding by id rather than by an email
343+
344+
53. Update the callback in `auth.ts` file
345+
346+
```
347+
async session({ token, session }) {
348+
console.log({
349+
sessionToken: token,
350+
});
351+
352+
if (token.sub && session.user) {
353+
session.user.id = token.sub;
354+
}
355+
356+
return session;
357+
},
358+
359+
async jwt({ token }) {
360+
// fecthing the user
361+
362+
if (!token.sub) return token;
363+
const exisitingUser = await getUserById(token.sub);
364+
if (!exisitingUser) return token;
365+
token.role = exisitingUser.role;
366+
367+
return token;
368+
},
369+
370+
```
371+
372+
#### you must be start seeing the role in the token
373+
374+
54. Update session function
375+
376+
```
377+
async session({ token, session }) {
378+
379+
if (token.sub && session.user) {
380+
session.user.id = token.sub;
381+
}
382+
383+
if(token.role && session.user){
384+
session.user.role = token.role // you will be seeing here a typescript error
385+
}
386+
387+
return session;
388+
},
389+
```
390+
391+
55. Update in `auth.ts` file
392+
393+
```
394+
if (token.role && session.user) {
395+
session.user.role = token.role as UserRole;
396+
}
397+
```
398+
399+
- and create a `next-auth.d.ts` file in root directory
400+
- and paste the code
401+
402+
```
403+
import { UserRole } from "@prisma/client";
404+
import NextAuth from "next-auth";
405+
406+
export type ExtendedUser = DefaultSession["user"] & {
407+
role: UserRole; // this is the type of role
408+
};
409+
410+
declare module "next-auth" {
411+
interface Session {
412+
user: ExtendedUser;
413+
}
414+
}
415+
416+
```
417+
#### Now you can see the role of the user in the session
418+

app/(protected)/settings/page.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { auth, signOut } from '@/auth'
22
import React from 'react'
33

44
const Settings = async () => {
5-
const user = await auth()
5+
const session = await auth()
6+
console.log(JSON.stringify(session?.user.role)) // session can be possibly null, so do optional chaining
67
return (
78
<div>
8-
{JSON.stringify(user)}
9+
{JSON.stringify(session)}
910
<form action={async () => {
1011
'use server'
11-
await signOut()
12+
await signOut() // exclusively for server actions
1213
}}>
1314
<button type='submit'>
1415
Singout

auth.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,40 @@ import NextAuth from "next-auth";
33
import authConfig from "@/auth.config";
44
import { db } from "./lib/database.connection";
55
import { PrismaAdapter } from "@auth/prisma-adapter";
6+
import { getUserById } from "./lib/actions/user.action";
7+
import { UserRole } from "@prisma/client";
8+
69
export const {
710
handlers: { GET, POST },
811
auth,
912
signIn,
1013
signOut,
1114
} = NextAuth({
15+
callbacks: {
16+
17+
async session({ token, session }) {
18+
if (token.sub && session.user) {
19+
session.user.id = token.sub;
20+
}
21+
22+
if (token.role && session.user) {
23+
session.user.role = token.role as UserRole;
24+
}
25+
26+
return session;
27+
},
28+
29+
async jwt({ token }) {
30+
// fecthing the user
31+
32+
if (!token.sub) return token;
33+
const exisitingUser = await getUserById(token.sub);
34+
if (!exisitingUser) return token;
35+
token.role = exisitingUser.role;
36+
37+
return token;
38+
},
39+
},
1240
adapter: PrismaAdapter(db), // prisma adapter is supported on non edge
1341
session: { strategy: "jwt" },
1442
...authConfig,

next-auth.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { UserRole } from "@prisma/client";
2+
import NextAuth from "next-auth";
3+
4+
export type ExtendedUser = DefaultSession["user"] & {
5+
role: UserRole;
6+
};
7+
8+
declare module "next-auth" {
9+
interface Session {
10+
user: ExtendedUser;
11+
}
12+
}

prisma/schema.prisma

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ datasource db {
1212
directUrl = env("DIRECT_URL")
1313
}
1414

15+
enum UserRole{
16+
ADMIN
17+
USER
18+
}
19+
20+
1521
model User {
1622
id String @id @default(cuid())
1723
name String?
@@ -20,8 +26,11 @@ model User {
2026
image String?
2127
password String?
2228
accounts Account[]
29+
role UserRole @default(USER)
2330
}
2431

32+
33+
2534
model Account {
2635
id String @id @default(cuid())
2736
userId String

0 commit comments

Comments
 (0)