Setting cookies
Answered
Blue Picardy Spaniel posted this in #help-forum
Blue Picardy SpanielOP
"use server";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { prodMode } from "@/config";
export async function redirectToAuth(redirectPath: string) {
cookies().set("redirect", redirectPath, {
path: "/",
secure: prodMode,
httpOnly: true,
maxAge: 60 * 10,
sameSite: "lax"
});
redirect("/api/auth");
}Cookies can only be modified in a Server Action or Route Handler.
I call this function only in server components.
I also use this in an api route:
const redirectPath = cookies().get("redirect")?.value;
cookies().delete("redirect");Answered by riský
if it was the url mismatch, you should store the redirect url in state: https://discord.com/developers/docs/topics/oauth2#state-and-security
103 Replies
as the error says, you cant set cookies in page.tsx or layout.tsx... instead you must use middleware or route handler (/server action)
Blue Picardy SpanielOP
if i remove the cookies function i get an error when redirecting too:
unhandledRejection: Error: NEXT_REDIRECT@riský as the error says, you cant set cookies in page.tsx or layout.tsx... instead you must use middleware or route handler (/server action)
Blue Picardy SpanielOP
it says a server action no?
i thought a server action was a server function defined by "use server" which is async
it is, but if you call it in "server context" it is just a normal function
Blue Picardy SpanielOP
so what do i need to do
@Blue Picardy Spaniel so what do i need to do
where are u using redirectAuth
@gin where are u using redirectAuth
Blue Picardy SpanielOP
in server components
@Blue Picardy Spaniel if i remove the cookies function i get an error when redirecting too: `unhandledRejection: Error: NEXT_REDIRECT`
redirect works by throwing error, so if you have try catch, its going to show this (just rethrow if next redirect error)
@Blue Picardy Spaniel i thought a server action was a server function defined by "use server" which is async
server action is not a server function
server actions are for handling form submission
this is just a function in rsc
or are u invoking that function trough a action?
Blue Picardy SpanielOP
Blue Picardy SpanielOP
on both cookies and redirect?
in your GlobalBan component
await redirectToAuth
Blue Picardy SpanielOP
didnt fix
u get the cookie error?
or something else
Blue Picardy SpanielOP
same error:(
Cookies can only be modified in a Server Action or Route Handler.try accessing the cookies instance trough a const
const cookieStore = cookies();
cookieStore.getor set
whatever
Blue Picardy SpanielOP
same error
remove the "use server"
directive
Blue Picardy SpanielOP
nope
ok we can debug
in your GlobalBan component
try accessing the cookies
just get your cookie and log it
Blue Picardy SpanielOP
that didnt work
what
Blue Picardy SpanielOP
wait i think ik
nvm
still broken
oh wait
@gin in your GlobalBan component
Blue Picardy SpanielOP
i can call it in the page yes
cool so no errors
Blue Picardy SpanielOP
i can call get in the redirectToAuth function but not set..
what?
cursed
Blue Picardy SpanielOP
i think im cooked
@Blue Picardy Spaniel i can call get in the redirectToAuth function but not set..
yeah as i said if it originated from server context and page.tsx/layout.tsx you cant set. but if its client then you can call server action who can set
thats something i missed out
thanks risky
oh yeah the error says it
Blue Picardy SpanielOP
im so confused
well there u go
Blue Picardy SpanielOP
so i have to make it a client component?
cookies only work on rsc or server actions and middleware
well what do you even want to do?
@riský well what do you even want to do?
Blue Picardy SpanielOP
let me explain my use case
im using discord oauth2 so when a user tries to go to /restricted and theyre not signed in it should redirect them to the auth page but when they come back from discord oauth it should send them back to /restricted
just trying to make a good user experience
i tried sending the redirect url with discord but that doesn't work for two reasons
id say use query params instead of cookies then
if i understand right ->
when a user goes to whatever /restricted it redirects to discord auth and when they come back they should be authed right?
when a user goes to whatever /restricted it redirects to discord auth and when they come back they should be authed right?
if it was the url mismatch, you should store the redirect url in state: https://discord.com/developers/docs/topics/oauth2#state-and-security
Answer
so whats the problem idk
@gin if i understand right ->
when a user goes to whatever /restricted it redirects to discord auth and when they come back they should be authed right?
Blue Picardy SpanielOP
that's all handled but i want them to go back to /restricted
rn it goes to a hardcoded /dashboard page every time
when originally they may have been at /restricted
so /restricted is basically ur dashboard or whatever
or is it a 403
@riský what were the 2 reasons
Blue Picardy SpanielOP
1. you have to pre-set the redirect uri on discord's dev portal but you cant use wildcards, you have to specifically set each url individually which isnt the main problem
2. when calling the https://discord.com/api/oauth2/token endpoint, the redirect_uri field has to be the same as the one that was used to generate the code using the https://discord.com/api/oauth2/authorize endpoint which wasn't possible but i cant remember why
2. when calling the https://discord.com/api/oauth2/token endpoint, the redirect_uri field has to be the same as the one that was used to generate the code using the https://discord.com/api/oauth2/authorize endpoint which wasn't possible but i cant remember why
yeah thats what i assumed so https://canary.discord.com/channels/752553802359505017/1286465261477691464/1286471379398430740 (i just like to abuse the state arg as not going to use it for anything else)
@gin or is it a 403
Blue Picardy SpanielOP
wdym
@Blue Picardy Spaniel wdym
i really dont know what he means (in relation to the error)
@riský yeah thats what i assumed so https://canary.discord.com/channels/752553802359505017/1286465261477691464/1286471379398430740 (i just like to *abuse* the state arg as not going to use it for anything else)
Blue Picardy SpanielOP
i already use state (idk what its for tho) as per lucia docs
hmm do you think there is a way to add onto state and give lucia everything but the end url back
Blue Picardy SpanielOP
hm this is all lucia uses state for:
const state = url.searchParams.get("state");
const storedState = cookies().get("token")?.value ?? null;
if(!code || !state || !storedState || state !== storedState) {
return new Response(null, {
status: 400
});
}so i dont actually pass it to lucia
oh it also stores cookie
Blue Picardy SpanielOP
yeah ive had no problems with those cookies tho
how does the lucia login work? you send it to a page which lucia redirects you to the discord oauth?
Blue Picardy SpanielOP
- generate a state and set it to your cookies
- make your own discord oauth2 url and pass state and redirect url (
- go to the discord oauth url
- in /callback lucia gets the code and state from your params and gets the stored state from cookies
- if the state in the params is not equal to the stored state, it errors
- get user info from code in params
- make your own discord oauth2 url and pass state and redirect url (
/callback)- go to the discord oauth url
- in /callback lucia gets the code and state from your params and gets the stored state from cookies
- if the state in the params is not equal to the stored state, it errors
- get user info from code in params
so in "generate a state and set it to your cookies", can you set the redirect cookie there
Blue Picardy SpanielOP
like attach it to the state?
doesnt need to be on state, could be cookie like you wanted
honestly it doesnt matter that much, i prefer state as less things can go weird
Blue Picardy SpanielOP
i wanted query originally
but for you i think it would just be more chaos
Blue Picardy SpanielOP
just testing hold on
yeah that works perfectly tysm
yay
@Blue Picardy Spaniel yeah that works perfectly tysm
u can mark his answer as solution btw
Blue Picardy SpanielOP
ty