Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 days ago.
Improve this question
`[server.js file as follows:
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import cors from 'cors'
import express from 'express'
import fileUpload from 'express-fileupload'
const app = express()
app.use(cors({
credentials: true
}))
app.use(cookieParser())
app.use(express.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(fileUpload())
export default app
Login request as Follows:
//Register A User
export const registerUser=catchAsynchErrors(async (req,res,next)=>{
const {name ,email,password}=req.body;
let myCloud=await cloudinary.v2.uploader.upload(req.body.avatar,{
folder:"avatars",
width:150,
crop:"scale"
});
const user=await User.create({name,email,password,avatar:{
public_id:myCloud.public_id,
url:myCloud.secure_url
}});
sendToken(user,201,res);
})
SendToken Funtion:
// Creating Tokens
const sendToken = (user, statusCode, res) => {
const token = user.getJWTToken()
// options for cookie
const options = {
expires: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000),
httpOnly: true
}
res.status(statusCode).cookie('token', token, options).json({
success: true,
user,your text``your text
token})
}
export default sendToken
//
Headers
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzZWI4Y2Q2NGM3MDY2Y2IwMTM0ODNkYiIsImlhdCI6MTY3NjQ3NzA1MiwiZXhwIjoxNjc2OTA5MDUyfQ.1O5gAt3hX0ujeCn4QjhadzsF1GhPB0foa60RNqgUdTU; Path=/; Expires=Mon, 20 Feb 2023 16:04:12 GMT; HttpOnly
X-Powered-By: Express
i want to add cookie in my browser but unexpectedly headers are received but it doesn't shows or set in browser.](``https://www.stackoverflow.com/``` ) ``
Related
I am writing a Node JS backend application and Vue JS front, in the API I need session for keep authenticate the users
I use this components on backend server:
express (4.18.2)
express-session (1.17.3)
connect-mongo (3.3.8)
MongoDB 4.4.4
This is the boot code:
// import libs ---
import config from 'config'
import bodyParser from 'body-parser'
import { v4 as uuidv4 } from 'uuid'
import routes from './routes' // custom folder
import express from 'express'
import session from 'express-session'
import MongoStore from 'connect-mongo'
// set costant ---
const app = express()
const secret = config.get('secret')
// body parser ---
app.use(bodyParser.json())
// setup session ---
app.use(session({
genid: function (req) { return uuidv4() }, // random id
secret,
store: MongoStore.create({ // connect to MongoDB fon Session storage
mongoUrl: db.extendedURL,
dbName: db.name,
// autoRemove: 'native',
// autoRemoveInterval: 10, // in minutes
ttl: 7 * 24 * 3600 // in seconds
}),
cookie: { // cookies manage
path: '/',
maxAge: 6000000,
httpOnly: false,
secure: false,
sameSite: false
},
stringify: false,
saveUninitialized: true,
resave: false,
rolling: false,
unset: 'destroy'
}))
// set server port (now run at localhost:5000) ---
app.set('port', 5000)
// set route ---
app.use('/', routes)
In ./route folder there are index.js imports perfectly
Here it is:
// import libs ---
import express from 'express'
const router = express.Router()
// routes ---
router.post('/login', function (req, res) {
const { body, session } = req
try {
session.user = body.user
console.log('user', session.user)
req.session.save(function (err) {
if (err) return res.status(400).json({ message: err })
return res.status(200).json({ message: 'You have successfully authenticated' })
})
} catch (err) {
return res.status(400).json({ message: err })
}
})
router.get('/test', function (req, res) {
const { session } = req
try {
console.log('session', session)
return res.status(200).json(session)
} catch (err) {
return res.status(400).json({ message: err })
}
})
export default router
When I try to call localhost:5000/login (post) I get all just fine, but when I call localhost:5000/test (get) I get a new session on the response and on MongoDB, it also happens whit multiple call on localhost:5000/test
Why express-session generate new session on every call? I really don't know, I spend few days in there and now i don't know how to do
EDIT (12/Jan/2023)
I managet to get it to work using this very simple CORS configuration on NodeJS server boot code:
app.use(cors({
origin: 'http://localhost:8080',
credentials: true
}))
and the header withCredentials: true on every simple http call from front
But this work only from localhost:8080
How can I do for call the Node JS server from other location without specify every IP addres?
Thank you
To allow every origin you can do
app.use(cors({
origin: '*',
credentials: true
}))
or
app.use(cors({
credentials: true,
origin: true
})
Source : Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
Im building a webserver with express, socketio and react. I have barely any experience when it comes to server and client communication, so Im trying to figure everything out.
Goal
Everytime a client connects to the webserver, it should be tested wether a cookie with the name "uid" exists. If it does, I want to print the value to the console, if there is no cookie with the name "uid" I want to create one.
Problem
Whenever I access http://localhost:3000 (on which adress the react client is hosted) and inspect the localhost request, there is no header with the name Set-header, same happens when I try to curl it. Also, in the Application tab the Cookies for http://localhost:3000 are completely empty. Accessing the cookie that should be set when a socket connects results in undefined or an empty object.
What I tried
The docs suggest setting cookie: true inside the options when creating the server, and prove that the cookie is set with a curl. I also tried setting the options to true on server creation (see server source code below), however when I try to curl the line Set-Cookie: io=G4J3Ci0cNDWd_Fz-AAAC; Path=/; HttpOnly; SameSite=Lax doesnt show up (see curl output below).
Following the docs again, I tried setting a cookie via headers["set-cookie"] = cookie.serialize("uid", "1234", { sameSite: "strict" }); inside io.engine.on("initial_headers"), however the cookie property on socket.request.headers.cookie remains undefined when trying to parse the cookie via let cookies = socket.request.headers.cookie; let parsed = cookie.parse(cookies ?? ""); //does not translate console.log(parsed); and thus the console output is only an empty {}.
I dont know what the difference between cookie based sticky session and application-cookies is, and I also dont know much about settings cookies and headers and all that stuff, maybe I am missing something obvious about the server/client side. Thanks in advance
Curl output:
C:\Users\stadl>curl "http://localhost:3000" -v
* Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.83.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: *
< Access-Control-Allow-Headers: *
< Content-Type: text/html; charset=utf-8
< Accept-Ranges: bytes
< Content-Length: 1711
< ETag: W/"6af-+M4OSPFNZpwKBdFEydrj+1+V5xo"
< Vary: Accept-Encoding
< Date: Sun, 25 Sep 2022 13:29:44 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
Server code:
const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const ports = require("../ports");
const cookie = require("cookie");
const SERVER_PORT = ports.get("server");
const CLIENT_PORT = ports.get("client");
const io = new Server(server, {
cors: {
origin: "http://localhost:" + CLIENT_PORT,
},
cookie: true,
});
io.engine.on("initial_headers", (headers, request) => {
headers["set-cookie"] = cookie.serialize("uid", "1234", { sameSite: "strict" });
});
io.engine.on("headers", (headers, request) => {
if (!request.headers.cookie) {
return;
}
const cookies = cookie.parse(request.headers.cookies);
if (!cookies.uid) {
headers["set-cookie"] = cookie.serialize("uid", "abc", { maxAge: 86400 });
}
});
io.on("connection", socket => {
console.log(`socket ${socket.id} connected`);
let cookies = socket.request.headers.cookie;
let parsed = cookie.parse(cookies ?? "");
console.log(parsed);
socket.on("disconnect", () => {
console.log(`socket ${socket.id} disconnected`);
});
});
server.listen(SERVER_PORT, () => {
console.log("Server is listening on http://localhost:" + SERVER_PORT);
});
Client code:
import React from "react";
import io from "socket.io-client";
import Navigation from "./components";
import { reload } from "./reload";
const ports = require("ports");
const SERVER_PORT = ports.get("server");
const socket = io.connect("http://localhost:4000");
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
DARKMODE: false,
};
}
componentDidMount() {
setInterval(reload, 1000);
}
toggleDarkMode() {
this.setState({
DARKMODE: !this.state.DARKMODE,
});
}
render() {
return (
<div className="app" data-theme={this.state.DARKMODE ? "dark" : "light"}>
<Navigation onDarkModeToggle={this.toggleDarkMode.bind(this)}></Navigation>
</div>
);
}
}
export default App;
----------------------------- EDIT --------------------------------
When activating the `show filtered out request cookies` in chrome on inspecting the localhost request, the cookie "uid" with the value "abc" gets displayed. But why is it getting filtered out?
Before I deploy, the app performed fine on localhost. But since I deployed my frontend (react) to Netlify and backend(node/express + mysql) to Heroku, all requests sent from the frontend started to get blocked by CORS policy, with the error message:
"Access to XMLHttpRequest at 'https://xxx.herokuapp.com/login' from origin 'https://xxx.netlify.app' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://xxx.app/' that is not equal to the supplied origin."
Most importantly, the value of my Access-Control-Allow-Origin header is literally the same as the origin stated.
Originally, I've tried to use a wildcard ("*"), but it seems that due to the withCredential problem, the system just can't allow that kind of vague statement.
I've also seen many people using Netlify.toml to tackle some configuration problems, but seems ineffective for me.
Is it the header's problem? If not, then what is the problem?
I really want to know what I should do to solve this error...
The console window of the app deployed:
Cors Error
My index.js in the server folder:
const express = require('express')
const mysql = require('mysql')
const cors = require('cors')
const session = require('express-session')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const port = 3010
const app = express()
app.use(express.json())
app.use(cors({
origin: ["https://xxx.app/"], // the link of my front-end app on Netlify
methods: ["GET", "POST"],
credentials: true
}))
app.use(cookieParser())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use(
session({
key: "userId",
secret: "subscribe",
resave: false,
saveUninitialized: false,
cookie: {
expires: 60 * 60 * 24
},
})
)
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "https://xxx.netlify.app/"); // the link of my front-end app on Netlify
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, DELETE, OPTIONS"
);
res.setHeader('content-type', 'application/json');
next();
});
const db = mysql.createPool({
// create an instance of the connection to the mysql database
host: 'xxx.cleardb.net', // specify host name
user: 'xxx', // specify user name
password: 'xxx', // specify password
database: 'heroku_xxx', // specify database name
})
...
app.get('/login', (req, res) => {
if (req.session.user) {
res.send({
isLoggedIn: true,
user: req.session.user
})
} else {
res.send({
isLoggedIn: false
})
}
})
...
app.listen(process.env.PORT || port, () => {
console.log('Successfully Running server at ' + port + '.')
});
My Frontend:
import React, { useEffect, useState } from 'react'
import '../App.css'
import './HeroSection.css'
import { Link } from 'react-router-dom'
import Axios from 'axios'
function HeroSection() {
Axios.defaults.withCredentials = true
let username = "";
const [name, setName] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(false)
const [isLoading, setLoading] = useState(true)
...
useEffect(() => {
Axios.get('https://xxx.herokuapp.com/login').then((response) => {
if (response.data.isLoggedIn) {
username = response.data.user[0].username;
}
setIsLoggedIn(response.data.isLoggedIn)
Axios.post('https://xxx.herokuapp.com/getLang', {
username: username,
}).then((response) => {
console.log(response.data);
})
Axios.post('https://xxx.herokuapp.com/getStatus', {
username: username,
}).then(response => {
setName(response.data[0].firstname + " " + response.data[0].lastname);
setLoading(false);
})
})
}, [])
if (!isLoggedIn || isLoading) {
return (
<div>
...
</div>
)
} else {
return (
<div>
...
</div>
)
}
}
export default HeroSection
By the way, I use ClearDB MySQL on Heroku and MySQL WorkBench for the database, which all works fine.
You could debug by doing something like:
const allowList = ["https://yyy.app/"];
// Your origin prop in cors({})
origin: function (origin, callback) {
// Log and check yourself if the origin actually matches what you've defined in the allowList array
console.log(origin);
if (allowList.indexOf(origin) !== -1 || !origin) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
UPDATE: it aparently works on firefox, I was using brave. I guess it's blocking the cookie with the session?? I don't know what to do about that.
I'm building an app with Vue, connecting through Axios to an API made with express.
I'm trying to use express-session to manage login sessions and auth. On my localhost it works great, but when I tried to use it from the site hosted on heroku, it breaks. The middleware that checks whether the session has an usuario property blocks the call.
I'm pretty sure it has to do with https instead of http. I tested it on localhost https with some generated credentials and it broke the same way.
The endpoint for login is quite long, but basically checks if the password you gave it is correct, and if it is, it sets req.session.usuario to an object with some user data. After that, when I check again for the session, usuario is not set.
The CORS middleware:
const cors = require("cors");
const whitelist = ["https://localhost:8080", "https://hosted-client.herokuapp.com"];
const corsOptions = {
credentials: true,
origin: (origin, callback) => {
if (whitelist.includes(origin))
return callback(null, true);
//callback(new Error("CORS error"));
callback(null, true);
},
};
module.exports = cors(corsOptions);
The session middleware:
const Redis = require("ioredis");
const connectRedis = require("connect-redis");
const session = require("express-session");
const RedisStore = connectRedis(session);
const redisClient = new Redis(
process.env.REDIS_PORT,
process.env.REDIS_HOST,
{password: process.env.REDIS_PASSWORD}
);
module.exports = session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SECRET,
saveUninitialized: false,
resave: process.env.STATE_ENV === "production",
proxy: true,
cookie: {
secure: process.env.STATE_ENV === "production",
httpOnly: true,
sameSite: "none",
// maxAge: 1000 * 60 * 30, // 30 minutos
},
});
A simple test auth middleware:
module.exports = function (req, _, next) {
if (!req.session || !req.session.usuario) {
const err = new Error("No se encontró una sesión");
err.statusCode = 401;
next(err);
}
next();
}
The Axios instance on the client:
require("dotenv").config();
import axios from "axios";
export default axios.create({
baseURL: process.env.VUE_APP_API,
headers: {
"Content-type": "application/json",
},
withCredentials: true,
});
I'm not sure if that's enough info, if not let me know.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
So I use React to upload a file to my express server, doing this localy works however when I push the code to my nginx express server I keep on getting Cors errors. How would I be able to solve this problem, I currently user cors package ?
app.use(cors({
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS",
"preflightContinue": false,
"optionsSuccessStatus": 204
}))
var multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, databasepath + 'pdf-folder/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
var upload = multer({ storage: storage })
router.post('/uploadfolder',[authJWT.authenticateJWT,authJWT.isAdmin,upload.single('file')], adminController.uploadfolder);
exports.uploadfolder = function (req,res,next){
let dates = JSON.parse(req.body.Dates)
const newFolder = new Folder_PDF(
{
name: req.file.originalname,
validFrom: dates.validFrom,
validTill: dates.validTill
}
);
newFolder.save((err,folder) => {
if(err){
return res.status(500).send({message: err});
}
return res.status(200)
})
}
And my front end is just a simple dataform, however since this is a cors error I bet it is a server error:
uploadFile = () =>{
let data = new FormData();
data.append( 'file', this.state.file, 'a file title' )
const options = {
onUploadProgress: (progressEvent) => {
const {loaded, total} = progressEvent;
let percent = Math.floor( (loaded * 100) / total )
if( percent <= 100 ){
this.setState({ uploadPercentage: percent })
}
if(loaded === total){
// window.window.location.reload()
}
}
}
axios.post(apiLink+'admin/uploadfolder', data, options).then(res => {
}).catch(err => console.log(err))
}
The problem wasn't really cors, it was a 413 error. The file was to large, you have to set it in your nginx config file: client_max_body_size 2M;
const cors = require('cors');
const app = express();
const whitelist = ['yor-domain-name']
const corsOptionsDelegate = function (req, callback) {
let corsOptions;
if (whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
} else {
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}