Next.js server actions auth

When I call from an action, the cookies are not sent - even if I insert “credentials”: “include”. Is there an example of how to call an external API via server actions?
11 Replies
KiNFiSH
KiNFiSH3w ago
have you added nextCookies()] plugin to your plugin lists. sever actions does not practically mutation browser info , you need the plugin to help you setting cookie with Set-Cookie header
Henrik
HenrikOP3w ago
Yes, I did But it didn't help
xephyr
xephyr3w ago
I think I'm misunderstanding something about how it's meant to set cookies, because I'm not using asResponse and returning it because it's in useActionState so it can't return Response
KiNFiSH
KiNFiSH3w ago
can you please share the snippets ? if your server action does not return or redirect, the client may not update as expected.
xephyr
xephyr3w ago
https://discord.com/channels/1288403910284935179/1361660287954194442/1361660664690511872 using Conform on the client to manage the form error states so the server action either returns a conform error response or redirects i'm not sure where the cookies are supposed to be set
KiNFiSH
KiNFiSH3w ago
you can do redirect since it causes client side navigation.
xephyr
xephyr3w ago
the session doesn't update though at least not for me (I've switched to using authClient instead, ditched useActionState with server actions)
KiNFiSH
KiNFiSH3w ago
may be something is affecting the responseHeader can you show me the how you are calling it on server actions
xephyr
xephyr2w ago
@KiNFiSH I've refactored it to use authClient now, but I'm still curious why the server action wasn't working so I've recreated it. Let me know what you think 🙂
export const signInEmailSchema = z.object({
email: z.string().email({ message: "Invalid email address" }),
password: z.string(),
});

export const SignInForm: FC<ComponentPropsWithoutRef<"div">> = ({
className,
...props
}) => {
const signInEmail = async (prevState: unknown, formData: FormData) => {
"use server";

const submission = parseWithZod(formData, {
schema: signInEmailSchema,
});
if (submission.status !== "success") return submission.reply();

try {
await auth.api.signInEmail({
body: submission.value,
});
} catch (error) {
if (error instanceof APIError) {
return submission.reply({
formErrors: [error.message],
});
}
}

redirect("/");
};
const [state, formAction, pending] = useActionState(signInEmail, undefined);
const [form, fields] = useForm({
lastResult: state,
onValidate({ formData }) {
return parseWithZod(formData, { schema: signInEmailSchema });
},
shouldValidate: "onInput",
});

return (
<form action={formAction} id={form.id} noValidate onSubmit={form.onSubmit}>
...
</form>
);
};
export const signInEmailSchema = z.object({
email: z.string().email({ message: "Invalid email address" }),
password: z.string(),
});

export const SignInForm: FC<ComponentPropsWithoutRef<"div">> = ({
className,
...props
}) => {
const signInEmail = async (prevState: unknown, formData: FormData) => {
"use server";

const submission = parseWithZod(formData, {
schema: signInEmailSchema,
});
if (submission.status !== "success") return submission.reply();

try {
await auth.api.signInEmail({
body: submission.value,
});
} catch (error) {
if (error instanceof APIError) {
return submission.reply({
formErrors: [error.message],
});
}
}

redirect("/");
};
const [state, formAction, pending] = useActionState(signInEmail, undefined);
const [form, fields] = useForm({
lastResult: state,
onValidate({ formData }) {
return parseWithZod(formData, { schema: signInEmailSchema });
},
shouldValidate: "onInput",
});

return (
<form action={formAction} id={form.id} noValidate onSubmit={form.onSubmit}>
...
</form>
);
};
KiNFiSH
KiNFiSH2w ago
Can use try using useTransition just to make sure it is not actually useActionState issue ?

Did you find this page helpful?