I keep getting
GET, HEAD
response, when authenticating github user. This application is using express, and react.
I tried many solutions when it comes to blocked by cors, and although some solutions that may work for some developers. None has work for me
for example a solution from another post, does not work.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
Api call
router.get('/auth/github', passport.authenticate('github', { session: true, scope: ['profile'] }) );
router.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
function(req, res) {
// Successful authentication, redirect home.
var token = jwt.sign({ id: req.user.id}, 'nodeauthsecret');
res.cookie("jwt", token, { expires: new Date(Date.now() + 10*1000*60*60*24)});
res.redirect('http://127.0.0.1:8001/dashboard');
console.log(token)
console.log('this works');
});
app.js (express setup)
var express = require('express');
var app = express();
var userRoute = require('./routes/users');
var postRoute = require('./routes/posts');
var bodyParser = require('body-parser');
var logger = require('morgan');
var models = require('./models');
var User = require('./models/user');
var session = require('express-session');
var cookieParser = require('cookie-parser') ;
var cookieSession = require('cookie-session');
var dotenv = require('dotenv');
var env = dotenv.config();
var cors = require('cors');
const port = process.env.PORT || 8000;
const passport = require('passport');
const path = require('path');
const allowOrigin = process.env.ALLOW_ORIGIN || '*'
// CORS Middleware
if (!process.env.PORT) {
require('dotenv').config()
}
if (!process.env.PORT) {
console.log('[api][port] 8000 set as default')
console.log('[api][header] Access-Control-Allow-Origin: * set as default')
} else {
console.log('[api][node] Loaded ENV vars from .env file')
console.log(`[api][port] ${process.env.PORT}`)
console.log(`[api][header] Access-Control-Allow-Origin: ${process.env.ALLOW_ORIGIN}`)
}
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret : 'nodeauthsecret',
resave: false,
saveUninitialized: true,
}));
// var corsOptions = {
// origin: 'http://example.com',
// optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
// }
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
require('./config/passport-github')(passport);
app.use(function(req, res, next) {
res.locals.user = req.user; // This is the important line
console.log(res.locals.user);
next();
});
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
app.use('/api/users', userRoute)
app.use('/api/posts', postRoute )
app.listen(port, () => {
console.log('[api][listen] http://localhost:' + port)
})
Redux action
export const signWithGithub = () => {
return (dispatch) => {
Axios.get('localhost:8000/auth/github', {
headers: {
'content-type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Credentials': true
},
crossdomain: true
}).then( (res) => {
console.log(res);
dispatch({type: SIGN_GITHUB});
});
}
}
Home.js
signGithub = () => {
this.props.signWithGithub();
};
...
<a onClick={this.signGithub}>
<Chip
label="Sign In with Github"
clickable
avatar={< Avatar alt = "Natacha" src = "https://avatars0.githubusercontent.com/u/9919?s=280&v=4" />}
component="a"
className={classes.chip}/>
</a>
Related
I have been trying to make a MERN stack project,and I was learning about sockets,but I am encountering this error when I try to use sockets:
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=3&transport=polling&t=O6F3vrY' from origin 'http://localhost:8000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
I have read many stackoverflow answers and tried to use their code,but the error is not getting fixed anyhow.
I am pasting my files here, please help me out!
index.js file
const cors = require("cors");
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
const port = 8000;
const expressLayouts = require('express-ejs-layouts');
const db = require('./config/mongoose');
// used for session cookie
const session = require('express-session');
const passport = require('passport');
const passportLocal = require('./config/passport-local-strategy');
const passportJWT = require('./config/passport-jwt-strategy');
const passportGoogle = require('./config/passport-google-oauth2-strategy');
const MongoStore = require('connect-mongo')(session);
const sassMiddleware = require('node-sass-middleware');
const flash = require('connect-flash');
const customMware = require('./config/middleware');
app.use(cors({ credentials: true, origin: 'http://localhost:8000' }));
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", req.header('Origin'));
res.header("Access-Control-Allow-Credentials", true);
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
// setup the chat server to be used with socket.io
const chatServer = require('http').Server(app);
const chatSockets = require('./config/chat_sockets').chatSockets(chatServer);
chatServer.listen(5000);
console.log('chat server is listening on port 5000');
app.use(sassMiddleware({
src: './assets/scss',
dest: './assets/css',
debug: true,
outputStyle: 'extended',
prefix: '/css'
}));
app.use(express.urlencoded());
app.use(cookieParser());
app.use(express.static('./assets'));
// make the uploads path available to the browser
app.use('/uploads', express.static(__dirname + '/uploads'));
app.use(expressLayouts);
// extract style and scripts from sub pages into the layout
app.set('layout extractStyles', true);
app.set('layout extractScripts', true);
// set up the view engine
app.set('view engine', 'ejs');
app.set('views', './views');
// mongo store is used to store the session cookie in the db
app.use(session({
name: 'codeial',
// TODO change the secret before deployment in production mode
secret: 'blahsomething',
saveUninitialized: false,
resave: false,
cookie: {
maxAge: (1000 * 60 * 100)
},
store: new MongoStore(
{
mongooseConnection: db,
autoRemove: 'disabled'
},
function (err) {
console.log(err || 'connect-mongodb setup ok');
}
)
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.setAuthenticatedUser);
app.use(flash());
app.use(customMware.setFlash);
// use express router
app.use('/', require('./routes'));
app.listen(port, function (err) {
if (err) {
console.log(`Error in running the server: ${err}`);
}
console.log(`Server is running on port: ${port}`);
});
chat-sockets.js in config folder
module.exports.chatSockets = function (socketServer) {
let io = require('socket.io')(socketServer,{
cors:{
origin:"http://localhost:8000"
}
});
io.sockets.on('connection', function (socket) {
console.log('new connection received', socket.id);
socket.on('disconnect', function () {
console.log('socket disconnected!');
});
});
}
chat-engine.js in assets/js
class ChatEngine {
constructor(chatBoxId, userEmail) {
this.chatBox = $(`#${chatBoxId}`);
this.userEmail = userEmail;
this.socket = io.connect('http://localhost:5000');
if (this.userEmail) {
this.connectionHandler();
}
}
connectionHandler() {
this.socket.on('connect', function () {
console.log('connection established using sockets...!');
});
}
}
Any help is sincerely appreciated.
I am getting this error when trying to do a get request from my vue app. I am running an express Node.js express app that is connected to my local Mysql server. I already have the headers set to allow my Vue app running on localhost:8081 to access the node server but I'm still getting the error. I have CORS installed on node and vue. My teamates are using the same code I am and not getting this but I am still getting the CORS errors(image for errors). Any help would be greatly appreciated. Thanks!
app.js for my node server
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const cors = require('cors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/courses');
var app = express();
var corsOptions = {
origin: 'http://localhost:8081',
}
app.use(cors(corsOptions));
app.options('*', cors());
app.get('http://localhost:8081', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'})
})
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
var mysql = require("mysql");
app.use(function(req, res, next){
res.locals.connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'course'
})
res.locals.connection.connect();
next();
});
app.use('/api', indexRouter);
app.use('/api/courses', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
course-services.js for rest requests to my node app
import axios from "axios";
var baseurl = "";
if (process.env.NODE_ENV === "development") {
baseurl = "http://localhost/api/";
} else {
baseurl = "/api/";
}
const apiClient = axios.create({
baseURL: baseurl,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Access-Control-Allow-Origin" : "*",
crossDomain: true
},
transformRequest: (data, headers) => {
let token = localStorage.getItem("token");
let authHeader = "";
if (token != null && token != "") authHeader = "Bearer " + token;
headers.common["Authorization"] = authHeader;
return JSON.stringify(data);
},
transformResponse: function(data) {
data = JSON.parse(data);
if (!data.success && data.code == "expired-session") {
localStorage.deleteItem("token");
}
return data;
}
});
export default {
getCourses() {
return apiClient.get("courses");
},
getCourse(id) {
return apiClient.get("courses/" + id);
},
addCourse(course) {
return apiClient.post("courses", course);
},
updateCourse(courseId, course) {
return apiClient.put("courses/" + courseId, course);
},
deleteCourse(courseId) {
return apiClient.delete("courses/" + courseId);
},
};
I don't know why your setting headers many times if you use cors() module you don't have to set header again
var corsOptions = {
origin: 'http://localhost:8081',
}
app.use(cors(corsOptions));
app.options('*', cors());
This route is enough and use as middleware for certain routes And at last, only fetch from http://localhost:8081 don't fetch from any random chrome dev console which will violent cors policy as you setting a specific port and domain as localhost:8081 and please check that you using 127.0.0.1:8081 if so it will again throw an error
only use http://localhost:8081
If you use 127.0.0.1 will not work cause the host don't match
Hope this will help with your problem
You have a custom header in your request:
"X-Requested-With": "XMLHttpRequest",
Either you need to remove it from request header or you need to support it in your server response header by setting it in 'Access-Control-Allow-Headers' :
if you think there might be more custom headers simply set it to *
res.setHeader('Access-Control-Allow-Headers', '*');
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
I want to add production, development and test environment in my node.js project I am not able to understand from where started below is my code I have seen many example but I am not able to understand
how to update according to enviornments. I have stored database credentials in .env file
db.config.js
require('dotenv').config()
var config = {
HOST: process.env.DB_HOST || "127.0.0.1",
USER: process.env.DB_USER,
PASSWORD: process.env.DB_PASSWORD,
DB: process.env.DB_NAME,
DIALECT: process.env.DB_DIALECT || "postgres"
};
module.exports = config;
models/index.js
const dbConfig = require("../config/db.config");
const Sequelize = require("sequelize");
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.DIALECT,
operatorsAliases: false,
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.user = require("./user")(sequelize, Sequelize);
db.role = require("./role")(sequelize, Sequelize);
db.items = require("./items")(sequelize, Sequelize);
db.role.belongsToMany(db.user, {
through: "user_roles",
foreignKey: "roleId",
otherKey: "userId"
});
db.user.belongsToMany(db.role, {
through: "user_roles",
foreignKey: "userId",
otherKey: "roleId"
});
db.ROLES = ["user", "admin"];
module.exports = db;
app.js
var express = require('express');
var bodyParser = require('body-parser');
var db = require('./models');
const logger = require('morgan');
const cors = require("cors");
var app = express();
db.sequelize.sync({ force: false }).then(() => {
console.log("Drop and re-sync db.");
});
app.use(cors());
app.use(logger('dev'))
app.use(bodyParser.json({
type: 'application/vnd.api+json'
})); // parse application/vnd.api+json as json
app.use(bodyParser.json({
limit: '50mb'
}));
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true,
parameterLimit: 50000
}));
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
res.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0");
next();
});
app.get('/', function (req, res) {
res.send('Welcome to Passport with Sequelize');
});
require("./routes/auth.routes.js")(app);
require("./routes/user.routes.js")(app);
require("./routes/items.routes.js")(app);
const PORT = process.env.PORT || 8000;
const server = app.listen(PORT, function(){
console.log("Listening on port: 8080");
});
// app.listen(PORT, () => console.log(`Listening on port: ${PORT}`))
module.exports = server;
Add another file called config.js in the same folder where app.js reside and write below code in config.js.
var environments = {};
environments.test = {
'port':3000,
'envName': 'test'
};
environments.development = {
'port':5000,
'envName': 'development'
};
environments.production = {
'port':8000,
'envName': 'production'
}
var currentEnvironment = typeof(process.env.NODE_ENV) == 'string' ? process.env.NODE_ENV : '';
var environmentToExport = typeof(environments[currentEnvironment]) == 'object' ? environments[currentEnvironment] : environments.test;
module.exports = environmentToExport;
As per the above file, every time you start the server, if you mention the environment(test, development or production) then it will check the port number for that environment and run server on that port. For example, localhost:3000 for test, localhost:5000 for development or localhost:8000 for production.
Now in your app.js file modify few lines.
var express = require('express');
var bodyParser = require('body-parser');
var db = require('./models');
const logger = require('morgan');
const cors = require("cors");
const config = require('./config');
var app = express();
db.sequelize.sync({ force: false }).then(() => {
console.log("Drop and re-sync db.");
});
app.use(cors());
app.use(logger('dev'))
app.use(bodyParser.json({
type: 'application/vnd.api+json'
})); // parse application/vnd.api+json as json
app.use(bodyParser.json({
limit: '50mb'
}));
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true,
parameterLimit: 50000
}));
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
res.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0");
next();
});
app.get('/', function (req, res) {
res.send('Welcome to Passport with Sequelize');
});
require("./routes/auth.routes.js")(app);
require("./routes/user.routes.js")(app);
require("./routes/items.routes.js")(app);
const PORT = config.port;
const server = app.listen(PORT, function(){
console.log("Listening on port: "+PORT + ' in ' + config.envName + ' environment.');
});
// app.listen(PORT, () => console.log(`Listening on port: ${PORT}`))
module.exports = server;
Now, you can run application in different environments.
Command will be NODE_ENV=test node app.js for test,
NODE_ENV=development node app.js for development and
NODE_ENV=production node app.js for production.
If NODE_ENV is not mentioned and then application will run on default environment test
I am trying to make session using express-session with passport in cross domain .I take help of following links
Sending credentials with cross-domain posts?
Passport js fails to maintain session in cross-domain
**I am getting below error**
Failed to load http://localhost:5000/users/login: Response to
preflight request doesn't pass access control check: The value of the
'Access-Control-Allow-Origin' header in the response must not be the
wildcard '*' when the request's credentials mode is 'include'. Origin
'http://localhost:3000' is therefore not allowed access. The
credentials mode of requests initiated by the XMLHttpRequest is
controlled by the withCredentials attribute.
here is my whole code
https://github.com/naveennsit/Cors
client index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="style/style.css" rel="stylesheet" type="text/css"/>
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="jquery.js"></script>
</head>
<body>
<script>
$(function () {
$.ajax({
url: 'http://localhost:5000/users/login',
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({id: 5}),
dataType: 'json',
xhrFields: {
withCredentials: true,
},
crossDomain: true,
success: function () {
console.log('success');
},
error: function () {
console.log('error')
}
});
})
</script>
</body>
</html>
server code
server.js
var app = require('./app');
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`app is running on ${PORT}`);
})
app.js
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const path = require('path');
const morgan = require('morgan');
const cors = require('cors');
const session = require('express-session');
const passport = require('passport');
const app = express();
// Middleware
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cookieParser());
app.use(cors());
app.use(cookieParser());
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, authorization");
res.header("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS");
next();
});
app.use(session({
secret: 'secret',
resave: false,
domain: '.localhost:3000',
saveUninitialized: false,
cookie: {
domain: '.localhost:3000',
maxAge: 24 * 6 * 60 * 10000
},
}))
app.use(passport.initialize());
app.use(passport.session());
//Routes
app.use('/users', require('./routes/user.route'))
module.exports = app;
controller.js
const passport = require('passport');
const passportConfig = require('../passport')
module.exports = {
login: async (req, res, next) => {
console.log(req.body);
try {
req.login(req.body.id, function () {
res.json({message: "Registration successfully"});
})
} catch (e) {
console.log(e)
}
},
}
passport.js
const passport = require('passport');
passport.serializeUser(function(id, done) {
console.log('ddd');
// console.log(user);
done(null, id);
});
passport.deserializeUser(function(id, done) {
console.log('deserializeUser');
done(null, id);
// db.User.findById(id, function (err, user) {
// done(err, user);
// });
});
routes
const express = require('express');
const router = require('express-promise-router')();
const controller = require('../controllers/user.controller');
router.route('/login',)
.post(controller.login)
module.exports = router;
I want to add session in cross-domain.I already apply cors plugin still getting same error
The easiest way is to use the node.js package cors. The simplest usage is:
var cors = require('cors')
var app = express();
app.use(cors());
When using withCredentials: true in ajax, cors need to configure as below.
app.use(cors({origin: 'http://localhost:3000', credentials: true}));
You are almost there to solve it. You need to send actually allowed host in Access-Control-Allow-Origin header value and not *
If you want to allow for all origins, then you can include req.headers.origin for Access-Control-Allow-Origin header value in your CORS middleware:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, authorization");
res.header("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS");
next();
});
Cannot get setted cookies within requests.
I set my cookie with
response.cookie('name', 'My name');
I would like to get my cookie this way, and it worked before, but I changed express configuration, and I don't know what seems to be the problem now.
request.cookies is and empty Object
My express configuration:
var express = require('express'),
api = require('./routes/api');
var app = express();
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
//app.use(express.bodyParser());
app.use(express.compress()); // New call to compress content
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
app.use(app.router);
app.use(express.methodOverride());
//app.use(express.static(__dirname + '/public'));
});
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
next();
});
app.configure('development', function () {
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function () {
app.use(express.errorHandler());
});
Setting Cookie:
exports.singIn = function (req, res) {
var mail = req.query.mail,
password = req.query.password;
return user.find({
mail: mail
}).then(function (d) {
var user = usersData(u);
res.cookie('mail', user.mail, { maxAge: 900000});
res.cookie('password', crypted, { maxAge: 900000});
res.json({ user: user });
return { user: user }
}).catch(function () {
res.json(400, {"error-tag": "error-sing-in"});
return {"error-tag": "error-sing-in"};
});
};
Getting Cookie:
exports.account = function (req, res) {
var mail = req.cookies.mail,
password = req.cookies.password;
//here req.cookies is an empty object. I don't know why?
};
An answer for 2017 ..
const cookieParser = require('cookie-parser');
const express = require('express');
const app = express();
app.use(cookieParser());
to get a cookie from an incoming request ..
let cookie = req.cookies['cookiename'];
to set a response cookie (this cookie will be sent on all future incoming requests until deletion or expiration) ..
res.cookie('cookiename', 'cookievalue', {
maxAge: 86400 * 1000, // 24 hours
httpOnly: true, // http only, prevents JavaScript cookie access
secure: true // cookie must be sent over https / ssl
});
to delete a response cookie ..
res.cookie('cookiename', 'cookievalue', {
maxAge: 0
});
It's kind of exaggerated to use an extra package ("cookie-parser"), when this is the middleware function you need:
function cookieParser(req, res, next) {
var cookies = req.headers.cookie;
if (cookies) {
req.cookies = cookies.split(";").reduce((obj, c) => {
var n = c.split("=");
obj[n[0].trim()] = n[1].trim();
return obj
}, {})
}
next();
}
app.use(cookieParser);
I couldn't use "cookie-parser" in my graphQL server because it was messing things up.