Hi all
recently I am learning about the auth.
I tried setting the accessToken and refreshToken for the auth.
Initially decided to use fetch for it...
For further actions, you may consider blocking this person and/or reporting abuse
Hi Man,
Thank you for explaining this in detail. Could you please tell me how i can send cookie from FE to BE using axios?
I am using react for FE and express for BE.
Here is my express server :
import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
import setupSocket from "./lib/socket.js";
import http from "http";
import dotenv from "dotenv";
// Load environment variables from .env file
dotenv.config();
// Routes import here
import postRoute from "./routes/post.route.js";
import authRoute from "./routes/auth.route.js";
import testRoute from "./routes/test.route.js";
import userRoute from "./routes/user.route.js";
import chatRoute from "./routes/chat.route.js";
import messageRoute from "./routes/message.route.js";
const app = express();
app.set("trust proxy", 1);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const cookieParserSecret = process.env.JWT_SECRET_KEY; // Secret key for signing cookies
app.use(cookieParser(cookieParserSecret));
app.use(
cors({
origin: process.env.CLIENT_URL || "localhost:5173", // Replace with your client domain
// methods: ["GET", "POST", "PUT", "DELETE"], // Uncomment to restrict HTTP methods
credentials: true, // Allow credentials (cookies)
})
);
app.use("/api/auth", authRoute);
app.use("/api/users", userRoute);
app.use("/api/posts", postRoute);
app.use("/api/test", testRoute);
app.use("/api/chats", chatRoute);
app.use("/api/messages", messageRoute);
const server = http.createServer(app); // Create HTTP server using Express app
const io = setupSocket(server); // Setup socket.io
const PORT = process.env.PORT || 8800;
server.listen(PORT, () => {
console.log(
Server is running on port ${PORT});});
-------- express server ends here -------------
here is my code for setting the Cookie in the BE:
res
.cookie("token", token, {
withCredentials: true,
httpOnly: true,
sameSite: "none",
secure: process.env.NODE_ENV === "production", // Set secure only in production
maxAge: age,
path: "/",
domain: process.env.CLIENT_URL || "localhost:5173",
})
.status(200)
.json(userInfo);
-------- Cookie code ends here -------------
Here is my FE axios code :
import axios from "axios";
const apiRequest = axios.create({
baseURL: process.env.VITE_API_BASE_URL,
withCredentials: true,
});
export default apiRequest;
-------- axios baseURL ends here -------------
here is how i making request
try {
const response = await apiRequest.post("/auth/login", {
username,
password,
});
-------- FE making post request ends here -------------
here is how i am trying to verify my token:
import jwt from "jsonwebtoken";
export const verifyToken = (req, res, next) => {
const token = req.cookies.token;
console.log("Token on backend: ", token);
if (!token) {
return res.status(401).json({
message: "You are not authorized!",
});
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET_KEY);
} catch (error) {
console.log(error);
}
};
-------- verify token ends here -------------
On localhost everything works fine but when i deploy my BE set the cookie but FE doesn't send the coockie to the BE.
i struggled alot and already tried many ways and spend many days on it. but nothing fixed my problem.
Please help me.
i will really be thankful for any lead or help.
domain: process.env.CLIENT_URL || "localhost:5173",This is the line I suspect. Might sound silly, but try
console.log(process.env.CLIENT_URL).The other thing I would suspect is that, the client and server are on different domains or say subdomains.
Try this, because if it is not a cors issue, then definitely the domain of client and server are different. In case the backend doesn't have been cname or DNS to the domain or a subdomain. You would need to do that.
Add in the front-end and back-end domain or subdomain like this and check.
domain: ["localhost", "example.com", "subdomain.example.com"]Hi @oatula ,
Thank you so much for your response. I tried this already, but it didn't fix the issue.
Here is my domain name for the frontend:
fr-real-estate-1.onrender.com
And here is my domain name for the backend:
fr-real-estate.onrender.com
Here are my cookie settings:
res.cookie("token", token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production", // Ensure HTTPS in production
maxAge: age, // Cookie expiry time
sameSite: "none",
path: "/", // Root path
domain: process.env.CLIENT_URL, // as you said after console it prints ----> fr-real-estate-1.onrender.com
});
console.log("cookie domain name", process.env.CLIENT_URL);
res.status(200).json(userInfo);
The problem is, when I change,
sameSite: "lax" to sameSite: "none",
my cookie is not being set after login. However, when I set sameSite: "lax", my cookie is being set, but it gets destroyed or is missing when I reload the page.
Can you please tell me what I should do in this case?
More i can login is this mean its not cors issue ?
but after login i get these below errors :
GET fr-real-estate.onrender.com/api/us... 401 (Unauthorized)
Error fetching notifications:
{message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}code: "ERR_BAD_REQUEST"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Request failed with status code 401"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: true, upload: XMLHttpRequestUpload, …}response: {data: {…}, status: 401, statusText: '', headers: Ds, config: {…}, …}stack: "AxiosError: Request failed with status code 401\n at p1 (fr-real-estate-1.onrender.com/asse... at XMLHttpRequest._ (fr-real-estate-1.onrender.com/asse... at is.request (fr-real-estate-1.onrender.com/asse... at async fetch (fr-real-estate-1.onrender.com/asse... Error
Can you please tell me where should i look for the fix. i am completely losted at this point. Your help will really be appreciated,
Thank you again!
"httpOnly:true This option is very crucial here. It tells the browser don't allow any JS touch it. Which means its totally secure. This is protected from the Cross Origin Attack"
The HttpOnly only stops js from reading the cookie not from sending it typically to a hostile endpoint that can access the session, for this attack to succeed you need "sameSite: "none" " which is basically bad
you should use sameSite -> lax | strict to be safe
nothing is totaly secure, code defensivly
Thanks a lot for stopping by and enlightening us. Will definitely take care and update it
hi atul
your article is good, only issue is you are vulnerable to csrf attacks if u keep
sameSite: "none"
security is hard and we are all learning all the time