Reputation: 339
I am trying to implement backend(express+node +supabase) authentication for my frontend(react)
/*BACKEND*/
//auth.js
import { supabase } from "../config/supabaseConfig.js";
export const checkMyAuthStatus = async (token) => {
try {
const { data, error } = await supabase.auth.getUser(token);
if (error) {
console.error("Failed to authenticate token:", error.message);
return false;
}
return !!data.user;
} catch (error) {
console.error("Error checking authentication status:", error);
return false;
}
};
export const mySignInFunc = async (email, pass, token) => {
try {
const { data, error } = await supabase.auth.signInWithPassword({
email: email,
password: pass,
options: {
captchaToken: token,
},
});
if (!error) {
return { data };
} else {
return { error };
}
} catch (error) {
console.log(error);
return { error: "Internal server error" };
}
};
//authRoutes.js
authRouter.get("/authStatus", async (req, res, next) => {
const token = req.cookies.access_token;
console.log("Cookies:", req.cookies); // Debug log
if (!token) {
return res.status(400).json({ error: "Authorization token is required" });
}
try {
const isAuthenticated = await checkMyAuthStatus(token);
if (isAuthenticated) {
res.status(200).json({ message: "User is authenticated" });
} else {
res.status(401).json({ message: "User is not authenticated" });
}
} catch (err) {
res.status(500).json({ error: "Server error" });
console.error(err);
}
});
Here req.cookies shows an empty object and error req._implicitHeader pops as error
authRouter.post("/signIn", async (req, res, next) => {
const { mail, pass, tok } = req.body;
const result = await mySignInFunc(mail, pass, tok);
const sess = await result.data.session;
if (result.error) {
res.status(400).json({ error: result.error });
} else {
// res.status(200).json({ data: result.data });
res.cookie("access_token", sess.access_token, {
httpOnly: true, // Ensures the cookie is only accessible via HTTP(S), not JavaScript
secure: true, // Ensures the cookie is only sent over HTTPS
maxAge: sess.expires_in * 1000, // Sets the cookie expiration time
sameSite: "strict",
signed: true,
partitioned: true,
});
res.status(200).json({ data: result.data });
}
});
//Frontend auth.ts
const isAuthenticated = async () => {
try {
const response = await axios.get(
`${String(import.meta.env.VITE_BASE_URL)}/auth/authStatus`,
{
withCredentials: true,
}
);
console.log("response", response.data);
return response.data ? true : false;
} catch (error) {
console.log(error);
return false;
}
};
export const checkAuthStatus = async () => {
try {
const isAuthenticateds = await isAuthenticated();
console.log("user is auth:", isAuthenticateds);
return isAuthenticateds;
} catch (error) {
console.log(error);
return false;
}
};
export const signInWithEmail = async (
mail: string,
pass: string,
tok: string,
router: any
) => {
try {
const response = await axios.post(
`${String(import.meta.env["VITE_BASE_URL"])}/auth/signIn`,
{ mail, pass, tok }
);
console.log(response.data);
if (response.data && response.data.data && response.data.data.session) {
// Navigate to the user home page
router.navigate({ to: "/user/Home" });
} else {
console.error("Invalid response structure:", response.data);
}
} catch (error) {
console.log(error);
}
};
{
"access_token": {
"expires": "2024-07-01T11:44:30.000Z",
"httpOnly": true,
"path": "/",
"samesite": "Strict",
"secure": true,
"value": "s:eyJhbGciOiJIUzI1NiIsImtpZCI6IkdNWGkrd2h1azB1QTZsQkYiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW5... }
}
But when I try to access this token in my /authStatus request it fails: 2) auth token is created still authStatus is consoled as false and backend shows following error in /authStatus: res._implicitHeader is not a function and when I console req.cookies it is empty
so how to correct the code
PS:
const corsOptions = {
origin: "http://localhost:5173",
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus: 200,
};
app.use(cors(corsOptions));
Upvotes: 0
Views: 106
Reputation: 1889
The missing of withCredentials: true in the below statement is the cause of failure. In this case, a cookie will be created and sent by the server to the client which you can see in the response. However the same cookie will not store in the Browser, consequently the subsequent request to server will not be able to include it. Please include withCredentials: true in the statement and try again.
const response = await axios.post(
`${String(import.meta.env["VITE_BASE_URL"])}/auth/signIn`,
{ mail, pass, tok }
);
Citation:
I am unable to set the cookies received from the response
Cookies not being saved in browser
Upvotes: 1