-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server Side providers/csrfToken/getCsrfToken is null on page reload on dev server #646
Comments
Working on a white-label, product, I get the same error after copying the internal pages |
I appreciate I don't think this fully resolves your query and will follow up, but I think it should resolve most of it: In 3.0 we made all the options camelCase to be consistent, so if you change 'signin' to 'signIn' here, that should resolve the problem with it not redirecting to your sign in page: pages: {
signIn: '/auth/signin',
error: '/auth/signin', // Error code passed in query string as ?error=
} (I appreciate this was an annoying change and could have been handled better, but is a one time growing pain for the lib.) The route I can't see any issues with that. I wonder if it's sometimes failing on dev due to the page being rebuilt by Next.js? Dev mode is a bit weird in that respect and can trigger multiple page calls (and some failures) and is a bit out of our control. @znk Did you also upgrade from a previous version or did you follow a tutorial or example from somewhere? I ask as a few folks have reported running into the same issue and am trying to work out if we have outdated docs / examples somewhere or if it's just confusing and we need to improve the error / warnings here. |
Hi, export async function getServerSideProps(context) {
const csrfToken = await csrfTokenF(context);
return { props: { csrfToken } };
} You can see the nextjs doc in https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering |
As I can see They just run another purpose by design and authors recommend to use But still You can't just change the function as it will require architecture change of big part of app, and since the |
Hi there! It looks like this issue hasn't had any activity for a while. It will be closed if no further activity occurs. If you think your issue is still relevant, feel free to comment on it to keep ot open. Thanks! |
Hi there! It looks like this issue hasn't had any activity for a while. To keep things tidy, I am going to close this issue for now. If you think your issue is still relevant, just leave a comment and I will reopen it. (Read more at #912) Thanks! |
@yournatalita I am facing this issue in production I'm getting www.example.com/api/auth/signin?csrf=true and doesn't signin to the page, though it was working fine in local host was signing in. I dont know whats wrong please help me. I am new to this. |
i m using but when i reload the suth/sign page it shows me null in providers causing an exception |
are using getInitialProps to get providers and others? |
I am also experiencing the same error and cannot get the csrfToken while rendering to the server side. import { useState } from 'react'
import Head from 'next/head'
import Image from 'next/image'
import Link from 'next/link'
import { FaTwitter } from 'react-icons/fa'
import { FcGoogle } from 'react-icons/fc'
import { signIn, signOut, useSession, getSession, getProviders, getCsrfToken } from 'next-auth/react'
import { redirect } from 'next/dist/server/api-utils'
import { useRouter } from 'next/router'
export default function Login({getProviders}) {
const router = useRouter();
const { data: session, status } = useSession();
const handleGoogle = async (e)=> {
e.preventDefault();
const response = await signIn("google");
}
const handleTwitter = async (e) => {
e.preventDefault();
const response = await signIn("twitter");
}
const [isChecked, setIsChecked] = useState(false);
const handleOnSubmit = async (e) => {
e.preventDefault();
let email = e.target.email.value;
let password = e.target.password.value;
const response = await signIn("email-password-credential", {
email,
password,
redirect: false,
callbackUrl: "http://localhost:3000"
});
await router.push("/");
console.log("email: "+email+", "+"password: "+password);
}
return (
<div className="">
<Head>
<title>로그인</title>
<meta name="description" content="example" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<div className="container mx-auto max-w-screen-md lg:my-25 p-4">
<div className="flex flex-col items-center mb-6">
<a className="hover:no-underline mb-2">
<div className="flex items-center justify-center">
<span className="font-semibold text-3xl tracking-tight">C</span>
<span className="font-semibold text-3xl tracking-tight text-[#E6CEA0]">OO</span>
<span className="font-semibold text-3xl tracking-tight">KIVEL</span>
</div>
</a>
<div className="text-2xl font-semibold text-center">
로그인
</div>
</div>
<div className="">
<div className="mb-4">
<button type="button" className="w-full px-6 py-2 bg-[#FFFFFF] rounded border shadow hover:bg-gray-50 active:bg-gray-100 mb-2"
onClick={handleGoogle}>
<div className="flex items-center justify-center">
<span className="text-2xl mr-2"><FcGoogle/></span>
구글 계정으로 로그인
</div>
</button>
<button type="button" className="w-full px-6 py-2 bg-sky-400 rounded text-white border shadow hover:bg-sky-500 active:bg-sky-600"
onClick={handleTwitter}>
<div className="flex items-center justify-center">
<span className="text-xl mr-2"><FaTwitter/></span>
트위터 계정으로 로그인
</div>
</button>
</div>
</div>
<div className="text-center">
또는
</div>
<form className="mx-auto" method="post" onSubmit={handleOnSubmit}>
<div className="mb-4">
<label className="block font-semibold" htmlFor="email">이메일</label>
<input
type="text"
id="email"
className="px-4 py-2 block w-full
border border-gray-400 rounded-md outline-none
text-base focus:outline-none focus:ring-1 focus:ring-gray-700 focus:border-gray-700"
placeholder="이메일을 입력해주세요"
/>
{isChecked &&
<div className="">
<span className="block text-red-600">이메일 또는 비밀번호가 잘못 입력되었습니다</span>
<span className="block text-red-600">가입되어 있지 않은 이메일을 입력하였습니다</span>
</div>}
</div>
<div className="mb-4">
<label className="block font-semibold" htmlFor="password">비밀번호</label>
<input
type="password"
id="password"
className="px-4 py-2 block w-full
border border-gray-400 rounded-md outline-none
text-base focus:outline-none focus:ring-1 focus:ring-gray-700 focus:border-gray-700"
placeholder="비밀번호를 입력해주세요"
/>
{isChecked &&
<div className="">
<span className="block text-red-600">이메일 또는 비밀번호가 잘못 입력되었습니다</span>
</div>}
</div>
<div className="flex items-center mb-4">
<input
type="checkbox"
id="rememberMe"
className="w-4 h-4 text-gray-700 mr-2 rounded-lg border-2 border-gray-300 after:bg-gray-800 focus:ring-0"/>
<label className="text-base mr-2" htmlFor="rememberMe">로그인 유지</label>
</div>
<div className="mb-4">
<button
type="submit"
className="w-full px-6 py-2 bg-stone-500 rounded-md border border-stone-500 text-white shadow hover:bg-stone-600 active:bg-stone-700">
로그인
</button>
</div>
<div className="flex justify-center divide-x divide-gray-300">
<Link href="/auth/signup">
<a className="pr-2">회원가입</a>
</Link>
<Link href="/auth/member/passwordSearch">
<a className="pl-2">비밀번호 찾기</a>
</Link>
</div>
</form>
</div>
</main>
</div>
)
}
export async function getServerSideProps(context) {
const { req } = context;
const session = await getSession({ req });
if (session) {
return {
redirect: { destination: "/" },
};
}
return {
props: {
providers: await getProviders(context),
csrfToken: await getCsrfToken(context),
},
};
} import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import TwitterProvider from "next-auth/providers/twitter"
import CredentialsProvider from "next-auth/providers/credentials"
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
authorization: {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code"
}
}
}),
TwitterProvider({
clientId: process.env.TWITTER_ID,
clientSecret: process.env.TWITTER_SECRET,
version: "2.0",
}),
],
pages:{
signIn: '/auth/login',
error: '/auth/error',
newUser: '/auth/signup',
},
callbacks: {
async jwt({ token, account }) {
// Persist the OAuth access_token to the token right after signin
if (account) {
token.accessToken = account.access_token
}
return token
},
async session({ session, token, user }) {
// Send properties to the client, like an access_token from a provider.
session.accessToken = token.accessToken
return session
}
}
})
It was run in development mode in the local environment, and no other settings were made. It is not implemented using DB, it only checks authentication on social media to get emails, nicknames, and profile images.
But it gave me this error. |
@gyull0210 if you do a GET request on the CSRF route (/api/auth/csrf) in your web browser or Postman does it return a valid CSRF token? I often run multiple NextJS instances and, being a bit absent minded, I often mix up the port mappings, eg. http://localhost:3001 vs http://localhost:3000 with what value is set in my .env file When I do, I also get [CLIENT_FETCH_ERROR], but slightly different than yours, such as:
Just wanted to share in hopes that it might inspire an idea for you. Good luck :) |
It pointed me in the right direction at least! After looking at next-auth's source code I saw that, if it's set, they use the env variable And I'm guessing next-auth automatically prefixes that url with A solution is to either unset |
I had this and the issue was that I was running the app on a different port to what was used in the i.e app was |
Your question
version: "^3.1.0"
mode: production
I use the credentials-signin as described here.
I get csrfToken on server-side as described in documentation
I redirect client-side as described in one of your issue treads
The problem is
When app redirects from another page via
Router.push
i get the correct token on signin page.When user reloads signin page manually, for example via F5, provider, csrfToken and getCsrfToken are null (cookies are fine) and console logs https://next-auth.js.org/errors#client_fetch_error error with javascript error SyntaxError: Unexpected token in JSON at position, and by "<" in it I can assume REST API returns a DOC page and breakes somehow.
Is this a bug or I am missing something?
When the person tries login with credentials without csrfToken it redirects to /api/auth/signin?csrf=true and not in my custom error page.
Is this a bug or designed behaviour? I don't need build-in auth page at all and I find it weird since it still creates an empty page https://prnt.sc/ucur6y which means for Next the URL is not breaking the 404 case.
Additional Info that might be related:
site.com
it doesn't work with bothNEXTAUTH_URL=http://site.com
andNEXTAUTH_URL=http://site.com/api/auth
What are you trying to do
I am trying to make a custom credentials signin page.
Things I'm trying to achieve:
Currently I use csrfToken client-side as workaround.
I would be happy with any ideas for changes in my settings or explanation of this behavoiur.
Feedback
Documentation refers to searching through online documentation, code comments and issue history. The example project refers to next-auth-example.
The text was updated successfully, but these errors were encountered: