NodeJS and ReactJS: Cookies do not set in browser - javascript

I am trying to send cookies in axios request from request handled in node js, NodeJS Does send cookies in response header but does not set in browser.
ReactJS
axios.post('http://localhost:4000/api/v1/auth/mflogin', {
data: wrapper,
},
)
.then((response) => {
setUser(true);
console.log(response.data);
navigate('/home');
})
.catch((error) => {
console.log('Error adding note.', error);
navigate('/countertwo');
});
This my backend:
One
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
next();
});
app.options('*', cors()) // include before other routes
const candidateAuth = require('./routes/Candidate/auth');
app.use('/api/v1/auth/', candidateAuth);
Two
if (validPassword) {
assign(User.dataValues, { Verified: true });
response.cookie('BasicCookie', 'BasicCookie',{httpOnly: true, sameSite: 'strict', secure: 'true',maxAge:1000000000000 }).status(201).json({
User,
});
} else {
response.status(400).json({ error: "Invalid Password" });
}
But it does send cookie to post man request,
But it does come in response header but do not set in cookies?
Any to help me here??

Related

I cam use POST and GET, but why I can't use DELETE in MongoDB Atlas

I'm learning the The University of Helsinki's Fullstack lesson, I can POST, and GET, but why I can't DELETE.
I used VS Code REST Client, this is REST Client code, I use it to test, POST and GET works good
POST http://localhost:3002/api/persons
Content-Type: application/json
{
"name": "re",
"number": "001"
}
###
DELETE http://localhost:3002/api/person/600974589e4e3b4a1562fd75
###
GET http://localhost:3002/api/person/600974589e4e3b4a1562fd75
This is my javascript code
index.js
app.post('/api/person', (req, res) => {
const body = req.body
if((!body.number) || (!body.name)){
return res.status(400).json({
error: 'Number or name is not exist!'
})
}
const newperson = new Phonebook({
name: body.name,
number: body.number,
date: new Date(),
})
newperson.save().then(savePerson => {
res.json(savePerson)
})
})
app.get('/api/person/:id', (req, res, next) => {
Phonebook.findById(req.params.id).then(person => {
if(person){
res.json(person)
}
else{
res.status(404).end()
}
})
.catch(error => next(error))
})
app.delete('api/person/:id', (request, response, next) => {
Phonebook.findByIdAndRemove(request.params.id)
.then(result => {
response.status(204).end()
})
.catch(error => next(error))
})
DELETE error
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Content-Length: 27
ETag: W/"1b-MMxRBlHxrLoIiEJggegnVLYwVTY"
Date: Sat, 23 Jan 2021 05:52:21 GMT
Connection: close
{
"error": "unkown endpoint"
}
I try to find the MongoDB Atlas log, but can't find it.
use this middleware in app.js at first file before call route
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE");
next();
});

Socket.io , NodeJS and ReactJS CORS error

As a starter, I have read a bunch of question concerning the same issue.
When I open the connection with the socket via React client the normal way, just the URL as parameter, I don't get this error, connection established.
But when I do this:
const io = ioClient(webSocketUrl, {
transportOptions: {
polling: {
extraHeaders: getAuthenticationToken()
}
}
});
The request return a CORS error everytime.
I have tried to:
Set the origin like so: io.origins(['*:*']);
app.use(function (req, res, next) {
res.setHeader(
"Access-Control-Allow-Origin",
req.header("origin") ||
req.header("x-forwarded-host") ||
req.header("referer") ||
req.header("host")
);
res.header(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
);
res.header("Access-Control-Allow-Headers", "X-Requested-With,content-type");
res.setHeader("Access-Control-Allow-Credentials", false);
next();
});
And also this:
app.use(cors());
app.options("*", cors());
None of the above worked.
I would appreciate any help.
Found the answer!
For anyone with the same problem, this is how I've done it:
const io = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin, //or the specific origin you want to give access to,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});

Why isn't my Fetch request sending custom headers in React-Native?

I am calling a fetch request akin to this.
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: new Headers({
'custom-header': 'custom header value'
})
}
)
.then(res=>{
/* code */
})
.catch(err=>{
/* code */
})
But it seems that the header is not being sent to the server. The server runs on Node.js, and I am attempting to reach it with React-Native.
I have allowed "access-control-allow-origin": "*" on the server, but to no avail.
I can also reach other endpoints on the server that don't require any headers.
And lastly, I have set the headers with both new Headers() and as an object.
What exactly am I missing to allow the headers to be sent? Is there a way to see exactly what is going on with my request in react-native?
It works in postman just fine.
EDIT:
I am using the cors middleware in my server.
app.use(cors())
appConfig.init(app);
Can you add these lines before using routes and try?
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, custom-header"
);
res.header("Access-Control-Expose-Headers", "custom-header");
next();
});
And if you are using express cors middleware, you can add allowedHeaders and exposedHeaders options.
https://github.com/expressjs/cors#configuration-options
note if these configuration replaces the default headers, you may need to add the default headers to the options.
app.use(
cors({
exposedHeaders: ["custom-header"],
allowedHeaders: ["custom-header"]
})
);
Lastly you had better to use fetch api like this to send headers:
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: {
"custom-header": "custom header value"
}
}
)
.then(res => {
/* code */
})
.catch(err => {
/* code */
})
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Be sure,you added the header in:
res.header(
"Access-Control-Allow-Headers",
"Your_OWN_header,...."
);

Access-Control-Allow-Credentials error -- nodejs

I am getting the cors error. Am I missing anything? Below is the code which I have and the error which I am getting.
App Info:
Back-end is uploaded on lambda using serverless npm === which created api-gateway.
Mongodb is hosted on aws-ec2 instance .
Front-end/React is hosted on s3 bucket.
Thank you so much!
Access to fetch at '[node.js api-url, which is hosted on api-gateway/lambda]' from origin '[front-end react-url, which is hosted on aws-s3 bucket]' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is 'false' which must be 'true' when the request's credentials mode is 'include'.
Node.js code:
db.initialize();
initAxios(defaults);
const app = express();
if (process.env.ENV === 'production') {
app.server = https.createServer(config.sslOptions, app);
} else {
app.server = http.createServer(app);
}
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.use(expressSession({
secret: process.env.JWT_SECRET_KEY,
resave: true,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
var corsOptions = {
origin: function (origin, callback) {
callback(null, true)
},
credentials: true
}
app.use(cors(corsOptions));
// I added the below part so maybe it would work but it didn't :)
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// I added the above part so maybe it would work but it didn't :)
app.use(morgan('combined', {
stream: logger.stream
}));
app.use(`/api/v${process.env.API_VERSION}`, router);
Front-end React Code:
export async function login(data) {
return fetch(`[api-url]auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
// credentials: 'same-origin',
body: JSON.stringify({
username: data.username,
password: data.password,
}),
})
.then((response) => {
return response.json()
})
.then(onSuccess)
.catch(onFail)
}
Before it was like this:
app.use(cors({
credentials: true,
origin: true,
}));
So I converted into:
app.use(cors(corsOptions));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Thank you!
Your API endpoint is the API Gateway, not the Lambda, so you need to enable CORS on the actual Gateway.
There are multiple ways of doing this, but if you are using Serverless Framework for your deployment, there is a very good tutorial for enabling CORS here.
The quick and dirty way is just to add 'cors: true' under 'events: -http:' when you're describing your function endpoint in your serverless.yml.
Example:
events:
- http:
path: product
method: post
cors: true

Response for preflight has invalid HTTP status code 404 angular js

I am trying to prepare a Delete request in AngularJS to a nodeJS local server:
this.deleteMusician = function(id) {
$http({
url: 'http://localhost:3000/musicians/' + id,
method: "DELETE",
data: {}
//processData: false,
//headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
console.log(data);
}).error(function (data, status, headers, config) {
console.log(data);
});
};
And my nodeJS route looks like this:
app.delete('/musicians/:id', musicians.delete);
The same request via PostMan works, but on Google Chrome i get:
OPTIONS http://localhost:3000/musicians/5628eacaa972a6c5154e4162 404 (Not Found)
XMLHttpRequest cannot load http://localhost:3000/musicians/5628eacaa972a6c5154e4162. Response for preflight has invalid HTTP status code 404
CORS is enabled:
var allowCrossDomain = function(req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
};
app.use(allowCrossDomain);
You will need to configure your node server to expect options method too.Check this other answer
so:
app.options('/musicians/:id', optionsCB);
and:
exports.optionsCB = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
next();
}

Categories