next-auth takes time to update auth status in Client Rendering #13359
Unanswered
dhavalveera
asked this question in
Help
Replies: 1 comment
-
|
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { jwtDecode } from "jwt-decode";
import { API_ENDPOINTS } from "../../../constants";
import { lruCacheFunc } from "../../../lib/cache";
import { createPublicAxios } from "../../../lib/axiosServer";
/**
* NextAuth configuration options
* Exported so it can be reused in getServerSession calls
*/
export const authOptions = {
// Configure authentication providers
providers: [
CredentialsProvider({
// The name to display on the sign in form (e.g. 'Sign in with...')
name: "credentials",
// Credentials configuration for the sign-in form
credentials: {
email: {
label: "Email",
type: "text",
placeholder: "your-name@gmail.com",
},
password: { label: "Password", type: "password" },
rememberMe: { label: "Remember Me", type: "rememberMe" },
},
/**
* Authorize function - called when user attempts to sign in
* @param {Object} credentials - Email, password, and rememberMe from sign-in form
* @returns {Object|null} User object if successful, null if failed
*/
async authorize(credentialsPayload) {
try {
const axios = createPublicAxios();
// Make API call to your backend for authentication
const response = await axios.post(API_ENDPOINTS.AUTH_SIGNIN, {
emailOrPhone: credentialsPayload.email,
password: credentialsPayload.password,
rememberMe: Boolean(credentialsPayload.rememberMe),
});
console.log("46 [...nextuath].js", { response });
// Check if login was successful (statusCode 200)
if (response.data && response.data.statusCode === 200) {
const accessToken = response.data.access_token;
// Decode the JWT token to extract user information
const decodedToken = jwtDecode(accessToken);
/**
* Decoded token structure:
* {
* customerRegistrationId: "uuid",
* emailAddress: "email",
* customerDetailsId: "uuid",
* name: "User Name",
* iat: timestamp,
* exp: timestamp (7 days if rememberMe=false, 30 days if rememberMe=true)
* }
*/
// Return user object with all necessary data
return {
id: decodedToken.customerRegistrationId,
email: decodedToken.emailAddress,
name: decodedToken.name,
customerDetailsId: decodedToken.customerDetailsId,
accessToken: accessToken,
tokenExpiry: decodedToken.exp, // Unix timestamp
tokenIssuedAt: decodedToken.iat,
rememberMe: Boolean(credentialsPayload.rememberMe),
};
}
const errorMessage =
response?.data?.message ||
response?.data?.error ||
"Invalid credentials. Please try again.";
// Return null if statusCode is not 200
throw new Error(errorMessage);
// return null;
} catch (error) {
console.error(
"Authentication error:",
error.response?.data || error.message
);
// Extract error message from response
const errorMessage =
error.response?.data ||
error.message ||
"Invalid credentials. Please try again.";
console.log(100, { errorMessage });
throw new Error(errorMessage);
}
},
}),
],
// Custom pages configuration
pages: {
signIn: "/auth/signin", // Custom sign-in page
signOut: "/auth/signin", // Redirect here after sign out
error: "/auth/signin", // Error page (redirect to signin with error)
// newUser: '/auth/welcome' // Uncomment if you want a welcome page for new users
},
// Callbacks for customizing JWT and session behavior
callbacks: {
/**
* JWT callback - called when JWT is created or updated
* This is where we store the access token and user data
*
* @param {Object} params
* @param {Object} params.token - The JWT token
* @param {Object} params.user - User object (only available on sign in)
* @param {Object} params.account - Account object (only available on sign in)
* @returns {Object} Updated token
*/
async jwt({ token, user, account }) {
// Initial sign in - user object is available
if (account && user) {
return {
...token,
accessToken: user.accessToken,
tokenExpiry: user.tokenExpiry,
tokenIssuedAt: user.tokenIssuedAt,
userId: user.id,
customerDetailsId: user.customerDetailsId,
email: user.email,
name: user.name,
rememberMe: user.rememberMe,
};
}
// Check if token is expired
const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
const expiryBuffer = parseInt(process.env.TOKEN_EXPIRY_BUFFER || "300"); // 5 minutes buffer
// If token is expired or about to expire
if (
token.tokenExpiry &&
currentTime >= token.tokenExpiry - expiryBuffer
) {
console.log(
"Token expired or about to expire. User needs to re-login."
);
// Return token with error flag - this will trigger sign out
return {
...token,
error: "TokenExpiredError",
};
}
// Token is still valid, return as is
return token;
},
/**
* Session callback - called when session is checked
* This is what gets returned to the client via useSession()
*
* @param {Object} params
* @param {Object} params.session - Session object
* @param {Object} params.token - JWT token
* @returns {Object} Updated session
*/
async session({ session, token }) {
// If there's an error in token (like expiry), return null session
if (token.error) {
return null;
}
// Add custom properties from token to session
session.user = {
...session.user,
id: token.userId,
email: token.email,
name: token.name,
customerDetailsId: token.customerDetailsId,
accessToken: token.accessToken,
tokenExpiry: token.tokenExpiry,
};
return session;
},
},
// Session configuration
session: {
strategy: "jwt", // Use JWT for session management
maxAge: 30 * 24 * 60 * 60, // 30 days
},
// JWT configuration
jwt: {
secret: process.env.NEXTAUTH_SECRET,
maxAge: 30 * 24 * 60 * 60, // 30 days
},
// Events - useful for logging and debugging
events: {
/**
* Fired when user signs out
* Clean up any additional data if needed
*/
async signOut({ token }) {
// Clear all cache on logout
lruCacheFunc.clear();
console.log("User signed out:", token.email);
// You could call your backend to invalidate the token here
},
/**
* Fired when session token is created
*/
async session({ session, token }) {
// Check if token is expired and force sign out
if (token.error === "TokenExpiredError") {
console.log("Token expired during session check");
}
},
},
// Enable debug messages in development
debug: process.env.NODE_ENV === "development",
};
/**
* Export NextAuth handler with our configuration
*/
export default NextAuth(authOptions);please help me |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
I'm using
"next-auth": "^4.24.13"and using"next": "16.0.3"and using Nextjs with Page Router & not using TS but using JS, and I am using NextAuth and wrapped the providers and session and all in the_app.jswhich is as below:but when I am checking
statusin the Client Side, it's not giving the updated status immediately, it's taking time to give me the updated auth statusthis is how I am using it, and this code is inside
header.jsand which is getting wrapped insidelayout.jsand thatLayout.jscode is wrapped to each pagesany idea why that after immediate login, this authStatus in the
headerfile is not getting updated and stayingunauthenticatedonly?and I am happy to share
[...nextauth].jscode file as well if requiredanyone can please guide & help me on this
Beta Was this translation helpful? Give feedback.
All reactions