next-auth
Im working on auth in this next app using next auth with google and credentials providers, and custom sign in and register page .
I definitely don't knw if I'm doing it in the right safest way to prevent my data from attackers.
I made only the route redirect u to the login page when u're not logged in i'll do the same for the rest of the pages later except blogs, home, sign in routes
Also the dashboard route will be protected route with user based auth
For now i wanna knw if my method is correct or not and what the things that i missed or did wrong. This is the github repo pls feel free to check it out : https://github.com/CLOG9/PuzChess/tree/main
For now i wanna knw if my method is correct or not and what the things that i missed or did wrong. This is the github repo pls feel free to check it out : https://github.com/CLOG9/PuzChess/tree/main
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
261 Replies
@smolcheeld
you on app dir or pages dir ?
App
Check the repo
u can write a middleware to do it as well. this way isnt too bad tho
i have done this way personally a few times as well in the form of making a HOC that redirects to other pages
this is the better way to do it tho. google around for some examples for this
I saw how to make middleware
Just two lines of code and u did it
yea do that then, its a safer option than HOC
Really?
yes
I thought the HOC is safer
btw u will still have to check if user is auth to make typescript happy for either way
Wdym
next auths useSession hook that returns data
it wont know if ur middleware has checked for it or not i believe
so ts will show data returned by useSession as session | null
Aaaah okay i got it
So i don't need getServerSession?
For the admin panel
yea its not needed
thats one of the advantages of middleware, u dont need to make HOCs for diff scenarios
Or just i have to make special key in the .env file for the admin user?
Yeh i'll use middleware then
write the middleware. for each page thats for authed users only, do an
if(status === "unauthenticated") redirect or do something
uhm u shld assume anything on the client can be hacked and so rely on making ur serverside apis secure
this way even if they hack the js and get to the admin page, all the fetch requests wont respond anythin coz u auth on the serverDo u have any real projects have this type of middleware?
not on the app dir
Aah okay
search it up, u shld easily find multiple examples for this
Nd in my repo i did right or?
For sure so just changing to middleware and make sure the admin route is safer
Im bit confused in the second one
wdym by second one
where are u makin requests ? i dont see any server code here
I didn't make the api yet
I'll put the code in the api route
basically what i meant by making it safe on server side is like on the api u do:
if(!authed || !isAdmin) throw unauthrozied
Ooooooooh 🤦♂️🤦♂️🤦♂️🤦♂️
Silly me
So i have to check in both client and server sides
yes always do validations on both the client and server.
and always on server at the very least
never do client side only
I got it now, but how the server or the API will get the and props?
Just passing them through the headers with axios or any lib?
uhm u get the session on the server
from next auth
🤦♂️🤦♂️🤦♂️🤦♂️🤦♂️🤦♂️
and have a property on the session called role or wotever
I can pass the data from session🤦♂️
Thanks bro im stupid today idk what happend to me lol
hi, i have similar question but im using pages route. do i need to use getServerSideProps on protected page to check the session?
@smolcheeld
u here ?
anyway i tried to make this in middleware but its making weird behaivor
when i load the page nd make a session(sign in ) it renders the other routes but when i navigate between them it gets frozen until i open the route in other tab.
and even if im logged in it requires me to re-log when i try to navigate to those routes
also i can access the routes from the URL so actually it still not protected
hmm thats weird. i havent used next auth with app dir so cant help u much there sorry
not necessarily. u can check if user is authed via middleware, in getserversideprops or inside the pages render function. all 3 options have diff user exps
is there any other suggestions
check out shadcn's taxonomy repo. that has a nextauth middleware example iirc
GitHub
GitHub - shadcn/taxonomy: An open source application built using th...
An open source application built using the new router, server components and everything new in Next.js 13. - GitHub - shadcn/taxonomy: An open source application built using the new router, server ...
@smolcheeld hey, i fixed the issues.
I just changed the middleware file to the src dir and it worked totally fine lol, anyway now im going to make user authorization and register using mysql but do u suggest using raw SQL or using drizzle? I remember that u said use prizma latter in other projects to learn SQL well. but what about now?
use drizzle coz it makes workin with ts easier and safer
i heared that i cant use drizzle with next auth ?
havent tried it with next auth, but i dont see why u shldnt
try askin in drizzles discord or searching for examples
check this
GitHub
Drizzle ORM support · nextauthjs next-auth · Discussion #7005
It would be amazing to support Drizzle, it's gaining good support and has a fantastic DX. https://github.com/drizzle-team/drizzle-orm
ah the adapter is a WIP
welp, u can try to follow and clone this https://github.com/nextauthjs/next-auth/pull/7165 and ask in their discord for help when u get stuck
GitHub
[WIP] feat(adapters): add Drizzle adapter by anthonyshew · Pull Req...
☕️ Reasoning
Introducing a drizzle-orm adapter!
With drizzle's increasing popularity, it's no surprise that there's a discussion for an adapter. This PR adds it.
🧢 Checklist
Documenta...
or use clerk or something else
🤷♂️
i think i'll use prizma instead and use cleark with drizzle in the next project
fair enough
thanks tho and sorry for annoying u
nah its all good
@smolcheeld u here?
I don't understand smthng, i saw a prizma t3 boilerplate nd it has session, verification token models
I don't understand why wee beed them . I mean yes u need to check session but doesn't nextauth do that for me? Or its just ob the client side ?
@CLOG read the next auth docs adapters section
The tldr is u need to store info somewhere - jwt or db, when u store on db u need to make some tables and shit first
And so for prisma the schema needs to look like that which the t3 boilerplate gives u
To make things clear: nextauth create a jwt for me or should i generate one?
Nah u dont need to do anything
Just follow the prisma setup for next auth and thats it
What user based role
Aah okay
Wdym ? Are u askin how to add role based auth ?
Well what will happen if i don't store the session on the db?
I havent tested this in next auth but with most auth solutions what happens is when u login and close the tab, next time u open the site again u will have to login again
Oh i miss spell it, what about user based role should i make a different jwt for it?
But if u store sessions,u wont have to login until the sess expires
Nah just add the role field to the session
Thats what i did for impl role based auth and it works well
And check it on the server
Yep
For promotion to admin, i made a route that can only be navigated by typing it in
And u have to give a server secret to chck if u are admin
Then if its correct the persons role gets promoted
For simple setups this works well eno
I think i should make a jwt only if im making reset password feature
Is that server secret a jwt or just an openssl key?
Openssl key
I think u are mistaking the purpose of jwt
U dont need a jwt for this either tbh
I didn't understand how the client would have that key
How
Well if its only gonna be for u and a circle of ppl u personally trust, u manually generate a key and add it to env vars and check against that
Otherwise wot u wanna do is have a table wit a single entry in which u store the key but everytime its used it gets rolled over. This way there is no risk of ppl using old keys to make their friends admin without u knowing
So that server secret must be typed in the url?
For this u generate a random crypto secure hash and store it on the users table. U send them an email with that hash in the route param and when they open that url u compare the hashes
Not necessarily. Totally upto u how and where u check it
If u wanna send links that ppl judt click and its done then do it that way
Or just make a login page
I think i understand a bit
Its not conceptually complicated tbh. The email part can be a bit of a pain to setup tho
And that crypto should be regenerated every time the specified user try to reset his password
Yes. In case if ppls email gets leaked u dont want ppl with old links resetting
Also u wanna store the key as hashed not in plain form, basically the same way we store passwords in db using bcrypt or some other algo
The reason u wanna hash is, if ur db gets leaked somehow, anyone can reset anyones password if its not hashed
Oh that's why then ...
Yea this is also why some companies dont let u see ur api keys more than once btw
I understand now but the only thing that i don't knw why i need it is why should store the session in the db
If its already known by the auth provider
u own ur auth with next auth
u arent checking against their server
I checked the next auth adapters section and its only showing how to make the model and add the prizma adapter to the options, is that it? Or should make api endpoints and POST the data?
u need to make a catch all api route atleast for pages dir
not sure about app dir, search around or look for examples
Sure
@smolcheeld why im getting this
is this local or on planetscale ?
planetscale
read the
Making schema changes with db push
partrelationMode = "prisma"
lol, thanks budd i don't know how i would make this app without your help:D
I think i miss spelled it but u got me anyway lol
xD
@smolcheeld i made this api route i still didn't add zod validation to it but i want to make an API key to it
and thats the create user function
so what u tryin to do here
Well i have two problems first i want to make a secret key to the header of this api to protect it
Also idk if should i make zod validation before or after encrypting the data
why are u doin this ?
either i dont fully understand what u are doin or u are doin something wrong
is this related to role based auth where u are tryin to promote the user to admin ?
I wanna make a GET method that fetchs all the users in the db but i don't want anyone to have the ability to fetch it except the admin(because i need all the uses to appear in the dashboard)
ah so u dont need to do this
all u do is check if the user is admin inside the route
i mean in the api request
Aaaa okay pretty simple then
What about the zod question?
i dont think u need to encrypt anythin
Really?
Why
I mean everyone highly suggest to do sort of bcrypt or something like that
wait what specifically are u tryin to encrypt here
Passwords and emails
u dont need to encrypt emails
only encrypt things that need to stay hidden
coz with any secure crypto algo like bcrypt its one way only
e.g. if u do myemail@com -> somehash, u cant do somehash -> myemail@com
Okay so encrypting passwords
yes encrypt passwords and the reset hash only
Oh one way then
also fyi, u cant decrypt somethin after u have encrypted it but u can compare them
yes, once its done, no matter what u wont get the original string
Well when i add new user to the db should encrypt first then do zod validation or the opposite?
so this what u wanna do -> get post request -> validate stuff with zod -> bcrypt hash password -> save everything to db
a POST yes
and if u are doin email resets, generate a random 32 digit key similar to what
openssl
command gives u, bcrypt hash that and store in the dbI don't understand
also there is no point encrypting after validation coz u wont be saving the user coz the data is invalid xD
Ps: I realized that im talking with u more than my mom lol, u're a life saver buddy
lmao
I think the point of encryption is protecting the database
uh basically u generate a random string, hash that and save it in ur db, when the user requests email reset, u send that in the email and u compare hashes to verify if the request made is legit
yes but ur idea of encryption is wrong. u dont encrypt the entire db, u encrypt certain fields of tables and u only do the encryption once before entering/updating that item/row
Should it be in one of the users table columns or just a temporary key?
put it inside the users table col
If im wrong what is the right method
this
No problem then, i think it would be the same for password reset too?
yep
That's great no need for jwt then
also if u are confused about encryption. we dont encrypt the db because like i said its a one way process for good algos
so we cant use the data coz it gets converted to meaningless hashes
I got it i just want to implement the best practices
Just two more questions pls🙂
yea what i said is compliant with them
go ahead, i will prob answer in a bit, got food to take
First is that the right method to make an api? (The code i sent)
Enjoy
Second if im not going to use any sort of jwt, when should i use them ?
And third (yes i knw i said two sorry ) i did session storage in the db but only for the OAuth, what about the credentials login ?
the logic is right but i am not sure if thats how next auth expects u to do it. i havent implemented email and password login on next itself. with nextauth i use social passwords and magic link. if i do email pass its when i have another backend.
Oh okay i see, i'll search for nextauth method then
the jwt is a loaded question, u shld honestly just google it. as for the creds provider question idk tbh
Okay, thank u bro i really appreciate ur help
I think its out of context but how u guys knw that huge stuff of backed functionality and best practices? Is there a specific source or path should i take to get that knowledge cuz the most thing i hate is when i don't knw that something exists even if i don't knw how to use it
Watch a basic tutorial and build stuff
But dont get trapped in tutorials. Watch the tut to only learn the foundational pieces
I do this since 3 years but the how u guys (lets say u in this example) know some things that aren't available in the tuts.
e.g. u said use middleware instead of the server session or sometimes i read the chat in the tech discussion room and i wounder how u get this info
a lot of those things are - we did something, searched how others are doing it and found better ways
^ do the above. doesnt matter in what order and u will learn stuff
since u dont know a lot, google even the obvious stuff. i am not a backend guy, i am a frontend one but even then i google stuff i already know just to see if there isnt a better way
U're correct, now i knw that using middleware in protecting routes is the great solution now and i didn't knw that before.
What about blogs, articles which ones u suggest to read
for blogs - tkdodo's for react query stuff, read brendanovich's form blog post
for specific stuff just read whatever article coz u cant really tell if its gonna be good or not
for backend, i highly encourage writing an auth from scratch, dont have to connect it to a frontend or anything. just make like a simple express app, that has a login and register page and u can sign in
Awesome! But sometimes i don't get certain type of answers to my questions by search, for example: what are the optimal use cases for middleware.
well for questions like these, first understand the meaning of it, see a few examples and that shld be eno to extrapolate use cases for it
In this project, i mada auth and role based and actually i learned a lot of stuff and every day i feel my app is getting more secure but still didn't reach the point that i can handle all the app problems
The meaning of middleware?
yes
if u know how stuff works on a fundamental level u can come up with use cases urself
for e.g. if u validate only in a client react comp, its gonna be less secure than doin it thru middleware because the first option is clientside and the second u are checkin on ur server
Well i guess it comes before the api so any data that needs a specific thing before it gets to the endpoint, it should come across the middleware.
And that's another question why should i check in the middleware and not in the api route lol
convenience
Either im dumb or just i miss something
middlewares also let u reuse code
u just need to sit down and make a backend side app tbh, or u could break down the taxonomy next js github repo i sent u
Hmmm i definitely have to do it, well based on ur info, i have to make the zod validation and the encryption in the middleware?
u dont need to do the validation in the middleware
or the encryption
Why
middleware = reusable logic u want to do before ur api route
so it works really well when u want to do the same thing everytime but things like validation which in one route u validate diff fields and in the other diff
its not as easy to setup to make it worth it. esp with typescript
and there is no reason to do encryption outside ur api route
Oooh like protecting routes
yea coz with protecting u will always only check if loggedin, thats it
Cuz the data should be sent encrypted?
I got it, but is there another use cases for middleware?
yea but think what u are goin to do after encrypting the password, add it to the db. so this is why u shld do it in the api route
because this is the core purpose of ur api route
not really. just reusable code. most middlewares u see will check for auth, do cors stuff, session management stuff, etc. stuff thats common to all/multiple routes
u can make validation middlewares and such but getting types to work with them is hard so ppl usually dont bother
To send and encrypt the data?
I think the easiest solution is doing it in the api route
yes it is
no its to add the user to the db. encrypting the password before u do that is just a step.
to make it simpler think about this, are u going to ever reuse encrypting ur password in a route other than create user and change password ?
prob not so it makes no sense to create a middleware for it
Well a question came to me, basically in my app when someone register the data went to the api route and it calls the prisma function to store the data, so i wondered why do i even need the api route (i know api routes are important ) i just can call the prisma function directly
Finally i got the middleware use case
coz u connect to ur db by a connection url that shld be kept secret
if u make direct requests on the client, anyone can find out ur connection url from the browser and can write stuff directly to ur db
U mean The url is connected with prisma client?
yes ur planetscale db url and secrets
next js separates public env vars (available on client and server) and private ones (only available on server)
Hmmm i got it now, what about the api route i see some ppl make a type of url in the api itself
Lemme send an example
wdym i dont understand what u mean by this
I'll show u an example
Why he used the jsonplaceholder api?
to get dummy data ?
like what are u really askin with this question
My question is should the api's have a type of urls inside or just he did that to simulate fetching from database
u can fetch inside api routes
and he also did it to simulate fetching from db
u can do this but dont fetch ur own server's other route, re use functions instead
I got it now, i guess i'll work on the form validation and the credentials login now.
Also i did some search about if nextauth is okay with my method of making the api and i found out that nextauth doesn't have an adapter for credentials so either hard code it or just use OAuth.
there is a credentials provider but u have to do a lot of implementation urself
Yes i used it but im talking about the prisma adapter it doesn't work for the credentials provider so idk i think i'll hard code a prisma function that stores a session in the users table
u can implement it with prisma sure
the creds provider is not a plug and play option. if u see the docs they even mention why
What about this? Does it help or just send the session directly to the db
Just refer the docs for this. But seems fine to me
So no need for db?
Or i have to store the jwt in the db too
no
just look at a tutorial or example its a lot to explain
what do u think
seems fine
this is cursed tho
well im having a bug, lemme show u
first i made a user in the db with a unique username, its created and returns 201 status. when i recreate another one with the same username it should returns an error with a message but instead of that its not creating the recreated user but returning 201 status and logging this in the console
- error unhandledRejection: { source: 'server' }
when i removed the hashing method everything worked fine but i need to hash the password.
i fixed it!i made some changes and i dont knw if im doing it right thats the repo pls if u dont mind check it https://github.com/CLOG9/PuzChess
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
@smolcheeld u here?
not home today, will check tmrw when i am back
Oh sorry, have fun
nah its ok :D
@smolcheeld u here?
Ye
first hooe your doing well.
im having a problem with middleware even if im logged in its asking me to re sign in and it keeps doing that
thats the next auth page :
and thats the middlare
so when i navigate to the dashboard route it requiring me to sign in even if im already signed in
so when i navigate to the dashboard route it requiring me to sign in even if im already signed in
write ur middleware like this instead https://github.com/shadcn/taxonomy/blob/main/middleware.ts
GitHub
taxonomy/middleware.ts at main · shadcn/taxonomy
An open source application built using the new router, server components and everything new in Next.js 13. - taxonomy/middleware.ts at main · shadcn/taxonomy
also i am doing great, hope u are too :D
trust me, im not lol
lmfao
take a look at that link, that shld work for u
hmmm i didnt get the most of it
can you explain?
basically u need to make a list of pages that shld be only accessible to signed in users
and then in the cb u check if they are authed or not and redirect them
just copy paste his code and replace your routes and stuff and thats it pretty much
i think its causing infinte redirects?
what is causing infinite redirects ?
Taxonomy
Taxonomy
An open source application built using the new router, server components and everything new in Next.js 13.
i'll check the options
i won't se credentials provider ever again
if im going to use it ill use it with clerk
idk its a hell
@smolcheeld if u don't mind i'll sent u the repo and check it
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
most things seem fine here
yep thats why i dont personally use it either. they intentionally dont help u out with to discourage it. sadly if thats what u need then its gonna be hard
I can give u the secrets and try it by urself
The sad thing is clients still ask for them to be in the design
is this ur own side project or for a client
if its for clients u shld really just use clerk or some other auth service
Its a side project
Im trying to learn auth
welp i dont have personal exp implementing cred provider so cant help u there
I think i'll switch to email provider theb
Then
Exactly why I haven’t been using next-auth for credential auth lmao
Believe me when i say this project gave me trauma
Hey, i used getServerSession instead of middleware cause it didn't help, now the problem is the session only return 3 values instead of the full data i tried to edit it in the callback
Like this :
But when i check it in the server component it doesn't work
@smolcheeld
U need to add ,user in the jwt cb and in the session cb acc to the docs
Callbacks | NextAuth.js
Callbacks are asynchronous functions you can use to control what happens when an action is performed.
i think that is available only for jwt strategy right? or both jwt and db sessions?
Not sure, check the docs
@smolcheeld should make friendship table relationship one to many or many to many?
many to many
coz if i am friends with X, he is also friends with me xd
something like that?
This works but u can also let prisma implicity handle it. https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations
Read the implicit section
sorry for diverting the conversation a bit, but i saw the heading was about next-auth and i needed to understand smthing.... So i've an application (pretty big) with multiple users and their roles and access level (thank goodness for the new next.js route grouping) i was able to group different UI for different users
now i'm implementing next-auth credentials providers and i will like to redirect different users based on their roles to their specific route group
i created a role-checking server component that run on the server and checks your session from next-auth, it then directs the user to their route... i really am beating myself if this is the best implementation for this use case or theres another way to run a function on next-auth sign-in handler
@smolcheeld please help, thanks
The thing that i learned from next auth is don't use their credentials provider. Use clerk or smthng else.
What is the session strategy?
its a seperate frontend from the backend... i only work on the frontend so i dont have much of an option... the backend developers control the authetication database
just get the session from next-auth on the server and run some checks before routing users to specific route... that's what i want to know if that is a good strategy or there's a better way of implementing role-based-acces control on the overall application
what i did in the middleware was check for each path if the user is authenticated and authorized to vie that route
So used the middleware here?
I guess u can do that, either all in one place ur Middleware or in each router if its a server component
yeah. the main question is how to route users after they sign-in with next-auth sign-in function... is it okay that i have a special route page for checking their roles or is there a better way to go about it
In the callbacks set the paths based on their role
After u get the session, check the role then redirect them based on that
Or use middleware either
Just make the checking in both client and server side
More important in server
yeah every authenticated is being done on the server... thanks
one more thing.... what i actually need is like a guide, i feel i'm doing it right but also need opionion from other devs... lets say after i created different route-groups for different users, inside each route there's also a very granular access level, lets say for example
i defined a sidebar that holds 7 different link menus, the head or let's say admin of that particular route give access and authorization to different users
the admin goes to the settings page, choose a particular user and gives them access to some part of the sidebar menu
that basically means every menu on the sidebar must go thru an authorization check. what i implemented was each sidebar menu gets the user details from the database and check if they are authorized to view that page or not
please is there a better way to go about it
cuz that basically mean each sub page of each menu will also go thru that check...
sorry for the long a** message
desperately need some clarity
So u're checking in every single route?
U can try middlewares for this
Ur current approach isnt bad either. Middleware is a more "clean" way to do it
U used tauri before right?
a bit yea
yeah exactly... how can i go about it correctly
sending the next-auth callback to the middleware or?? a bit confused
Since i used database session as my strategy i used server components to check the user roles
So make sure u use them
U check the role in the middleware and redirect the user based on that
thanks
U still can use middleware tho
ohh yeah, already implemented that... just extra checks and making sure the frontend authentication is perfect
Im looking to make a feature that allows me to use an external printer
Make sure to query that via an api
u just check it in the middleware. look at this for e.g. https://github.com/shadcn/taxonomy/blob/main/middleware.ts
GitHub
taxonomy/middleware.ts at main · shadcn/taxonomy
An open source application built using the new router, server components and everything new in Next.js 13. - shadcn/taxonomy
interesting. would suggest u check the stuff it supports first tho coz when i tried it i found very often i need x but tauri doesnt have it and electron does
I see, electron is cursed tho but it is what it is
using a cursed thing is better than somethin that literally doesnt do what u want tho 🤷♂️
Even if the performance is the tradeoff?
yea. somethin workin will nearly always be better than nothin at all.
🙌
few minutes into the repo and i have already refactored a bit🫡
yea its a great resource fr. have fun with ur learning :D
GitHub
[feat] Provide print API · Issue #4917 · tauri-apps/tauri
Describe the problem Tauri lacks a print API and this make it very difficult for electron based apps that perform lots of work with printers to migrate to Tauri, there are many use cases Unable to ...
i think electron is the way for this project
yea tauri has lot of shit electron doesnt
electron is slow
vs code and discord are electron
it will be fine for ur usecase unless ram is ur issue
basically im making a store management app. user receipt, stock and revenue,etc.. but i want to make it with complex ui (shadows, animations )
electron shld be fine for this
am i able to use react stuff with it? like framer motion, tailwind?
u can use any framework u want with it
I'd be careful with animations for such a system. I've made similar industrial applications and there is nothing more annoying to a worker putting in a hundred orders per day, than long-winded or flashy animations
yes
although idk why u would want next with it
the animations im trying to make just the page transitions, pop out , fades in/out
spinners
how would i handle the backend (works local)?
oh i thought this purely a clientside thing
yea t3 shld be pretty good for this or next app dir if uwant that
im going to use sqlite for the records
trpc sounds pretty handy for this project
please how can i solve this error, i cant seem to use the apostrophe
i just started using typescript
You can write it as {`Text with apostraphe here
}
any type of string declaration works in there not just
but thats just plain text, i wasnt even evaluating an expression... what about if my database returns an apostraphe??
vars dont have this problem. the problem here is a js syntax problem nothin else.
alright... thank you
Yes, except you mean a hash 🙂
yea i meant hashes