So I am trying to get httpOnly cookies from my express server and calling the api from react app using axios. But when I make the post request, no cookies are being set in my browser. I want to store token in cookies from my api and send it with every req from there on.
My index.js file
const express = require('express');
const bodyParser=require('body-parser');
const cors = require("cors");
const cookieParser=require('cookie-parser');
const app = express();
const ACCESS_TOKEN_SECRET=process.env['ACCESS_TOKEN_SECRET']
app.use(bodyParser.json());
app.use(cookieParser())
app.use(cors({credentials:true,origin:'https://yqn21.csb.app'}))
const videos=require("./routes/videos.router.js")
const signup=require("./routes/signup.router.js");
const login=require("./routes/login.router.js");
const likedvideos=require("./routes/likedvideos.router.js")
const { initializeDBConnection } = require("./db/db.connect.js")
//called before any route handler
initializeDBConnection();
app.use("/videos",videos);
app.use("/signup",signup);
app.use("/login",login);
app.use("/likedvideos",likedvideos);
app.get('/', (req, res) => {
res.send('Hello Express app!')
});
/**
* 404 Route Handler
* Note: DO not MOVE. This should be the last route
*/
app.use((req, res) => {
res.status(404).json({ success: false, message: "route not found on server, please check"})
})
/**
* Error Handler
* Don't move
*/
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ success: false, message: "error occured, see the errMessage key for more details", errorMessage: err.message})
})
app.listen(3000, () => {
console.log('server started');
});
My login route
require('dotenv').config();
const express = require("express");
const router = express.Router();
const { User } = require("../models/user.model")
const bcrypt = require('bcrypt');
const jwt=require('jsonwebtoken')
router.route('/')
.post(async (req, res) => {
try {
const user = req.body
const userFromDb = await User.find({ username: user.username });
console.log("10", userFromDb)
if (userFromDb.length > 0) {
try {
bcrypt.compare(user.password, userFromDb[0].password, function(err, cryptRes) {
if (err) {
throw err
}
if (cryptRes) {
const mySecret = process.env.ACCESS_TOKEN_SECRET
console.log(mySecret);
const accessToken=jwt.sign(userFromDb[0].id,mySecret)
res.header('Access-Control-Allow-Origin', 'https://yqn21.csb.app');
res.header('Access-Control-Allow-Credentials',true);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.cookie('accessToken',accessToken,{httpOnly:true,secure:true,sameSite:"none"}).json({ success: true, userFromDb,accessToken });
}
else {
res.status(403).json({ success: false, message: "Invalid Password" })
}
})
} catch (err) {
res.json({ success: false, message: "Something went wrong", err, userFromDb })
}
}
else {
res.json({ success: false, message: "User not found" })
}
} catch (err) {
res.json({ success: false, message: "Error fetching the user", err })
}
})
module.exports = router
My react POST method
async function postData(field) {
try {
const data = field;
console.log("Line 33", data);
const response = await axios.post(
"https://Video-Lib-Backend.adityanair14.repl.co/login",
data,
{ withCredentials: true, crossDomain: true }
);
console.log(response);
if (response.data.success === true) {
localStorage.setItem("loginState", true);
} else {
localStorage.setItem("loginState", false);
}
} catch (err) {
console.log(err);
}
}
Note:-
- I am making the request cross domain.
- I am not working on local host, instead in online host- repl and codesandbox. The links for the projects is given below. Just refer to the login.js file in codesandbox and login.router.js in repl.
https://codesandbox.io/s/youtube-lib-yqn21?file=/src/pages/Login.js:942-1664
https://replit.com/@AdityaNair14/Video-Lib-Backend#routes/login.router.js