I try to configure the csurf node module for an API that does not use the cookie and session, but it has bearer token authentication.
Below is the code that is what i tried. When i run the below code and getting the below error
Error: misconfigured csrf
at csrf (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/csurf/index.js:71:19)
at Layer.handle [as handle_request] (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:317:13)
at /Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:335:12)
at next (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:275:10)
at expressInit (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:317:13)
at /Users/saravanan/Documents/Development/nodejs/csurf-demo-1/node_modules/express/lib/router/index.js:284:7
** Code Snippet **
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express();
app.use(csrf());
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.get('/form', function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, function (req, res) {
res.send('data is being processed')
});
var PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
When I try with the below code that looks up for the header to validate the token, i am getting the error as cannot read session of undefined.
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({
value: (req) => {
var csrfToken = req.body._csrf || req.headers["x-csrf-token"];
return csrfToken;
},
cookie: false
})
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express();
app.use(csrfProtection());
app.get('/form', function (req, res) {
// pass the csrfToken to the view
// res.sendStatus(200);
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, function (req, res) {
res.send('data is being processed')
});
var PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
How can the API be secured using either the auth token or via the csrf tokens?
please check:
The call to app.use(csrf()) must be set after app.use(cookieParser()) AND app.use(session({...}).
I've got into the same trouble. I don't have neither session nor cookies but JWT tokens. For now I am going to implement CSRF protection with jwt-csrf module. I think it is totally fit to my need and needs of topic starter.
Related
When running my app.js I get this in the terminal:
express-session deprecated undefined resave option; provide resave option node_modules\admin-bro-expressjs\plugin.js:176:14
express-session deprecated undefined saveUninitialized option; provide saveUninitialized option node_modules\admin-bro-expressjs\plugin.js:176:14
express-session deprecated req.secret; provide secret option node_modules\admin-bro-expressjs\plugin.js:176:14
express-session deprecated req.secret; provide secret option app.js:34:5
this is what I have in my process.env :
SESSION_SECRET = "This is my final project of undergrad!"
when I try to load the page on localhost this is what I get so it won't let me see any of my webpage work:
secret option required for sessions
Error: secret option required for sessions
at session (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express-session\index.js:200:12)
at Layer.handle [as handle_request] (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express\lib\router\index.js:317:13)
at C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\express\lib\router\index.js:275:10)
at SendStream.error (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\serve-static\index.js:121:7)
at SendStream.emit (events.js:315:20)
at SendStream.error (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\send\index.js:270:17)
at SendStream.onStatError (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\send\index.js:421:12)
at next (C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\send\index.js:764:28)
at C:\Users\lil_s\Downloads\Rich Internet Applications Spring 2021\EAZ6NEJsports\EAZ6NEJsports-master\node_modules\send\index.js:772:23
at FSReqCallback.oncomplete (fs.js:183:21)
Here is app.js below in full as requested by Deepak on their comment:
const dotenv = require("dotenv").config();
const createError = require("http-errors");
const express = require("express");
const path = require("path");
const cookieParser = require("cookie-parser");
const logger = require("morgan");
const mongoose = require("mongoose");
const session = require("express-session");
const passport = require("passport");
const flash = require("connect-flash");
const Category = require("./models/category");
var MongoStore = require("connect-mongo")(session);
const connectDB = require("./config/db");
const app = express();
require("./config/passport");
// mongodb configuration
connectDB();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
// admin route
const adminRouter = require("./routes/admin");
app.use("/admin", adminRouter);
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")));
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: mongoose.connection,
}),
//session expires after 3 hours
cookie: { maxAge: 60 * 1000 * 60 * 3 },
})
);
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
// global variables across routes
app.use(async(req, res, next) => {
try {
res.locals.login = req.isAuthenticated();
res.locals.session = req.session;
res.locals.currentUser = req.user;
const categories = await Category.find({}).sort({ title: 1 }).exec();
res.locals.categories = categories;
next();
} catch (error) {
console.log(error);
res.redirect("/");
}
});
// add breadcrumbs
get_breadcrumbs = function(url) {
var rtn = [{ name: "Home", url: "/" }],
acc = "", // accumulative url
arr = url.substring(1).split("/");
for (i = 0; i < arr.length; i++) {
acc = i != arr.length - 1 ? acc + "/" + arr[i] : null;
rtn[i + 1] = {
name: arr[i].charAt(0).toUpperCase() + arr[i].slice(1),
url: acc,
};
}
return rtn;
};
app.use(function(req, res, next) {
req.breadcrumbs = get_breadcrumbs(req.originalUrl);
next();
});
//routes config
const indexRouter = require("./routes/index");
const productsRouter = require("./routes/products");
const usersRouter = require("./routes/user");
const pagesRouter = require("./routes/pages");
app.use("/products", productsRouter);
app.use("/user", usersRouter);
app.use("/pages", pagesRouter);
app.use("/", indexRouter);
// 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");
});
var port = process.env.PORT || 3000;
app.set("port", port);
app.listen(port, () => {
console.log("Server running at port " + port);
});
module.exports = app;
If there is anything else you need me to provide to help, please let me know! Thanks in advance everybody!
I discovered today that repl.it stopped parsing .env files, so you have to add your environment variables to the secrets section instead.
Hello guys I am working with node js to use dialogflow chat bot ,
I am trying to get parameters from http request post methode
I used postman for that and yes I did set up the content type to json in the header , I have the following code for my request body :
{
"text":"hello"
}
and the following link
http://localhost:5000/api/df_text_query
I have the following index.js file :
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
require('./routes/dialogFlowRoutes')(app);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
app.get('/',(req , res)=>{
res.send({'hello':'Johnny'});
});
const PORT = process.env.port || 5000;
app.listen(PORT);
this my dialogflowRoutes.js file :
const dialogflow = require('dialogflow');
const config = require('../config/keys');
const sessionClient = new dialogflow.SessionsClient();
const sessionPath = sessionClient.sessionPath(config.googleProjectID, config.dialogFlowSessionID);
module.exports = app => {
app.get('/', (req, res) => {
res.send({ 'hello': 'world!' })
});
app.post('/api/df_text_query', async (req, res) => {
console.log(req.body)
const request = {
session: sessionPath,
queryInput: {
text: {
text: req.body.text,
languageCode: config.dialogFlowSessionLanguageCode
}
}
};
let responses = await sessionClient
.detectIntent(request);
res.send(responses[0].queryResult)
});
app.post('/api/df_event_query', (req, res) => {
res.send({ 'do': 'event query' })
});
}
this is the error I get when I send the following request
dialogFlowRoutes.js:17
text: req.body.text,
^
TypeError: Cannot read property 'text' of undefined
Order in which you initialize middleware matters.
You must parse body before you act on it. Move your routing middleware after you initialize bodyParser, like below:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
require('./routes/dialogFlowRoutes')(app);
I'm making a POST request from a React front-end using axios to an endpoint to save some data to my DB (MongoDB). I'm getting an error that one cannot read property 'name' of undefined. I think that's occurring because req.body is undefined but I can't understand what's wrong with my axios request. I logged all the parameters and they are there (not undefined). The axios request and the endpoint are written below. Any help will be appreciated. Thanks!
Axios Request
const uploadElement = async (name, HTMLCode, JSCode, CSSCode, screenshot) => {
console.log(name)
try {
await axios({
method: 'post',
url: '/api/elements',
data: {
name: name,
HTMLCode,
JSCode,
CSSCode,
screenshot
}
});
} catch (e) {
console.log(e);
}
}
Endpoint for POST Request
router.post("/", upload.single("screenshot"), async (req, res) => {
try {
const newElement = new Element({
name: req.body.name,
JSCode: req.body.JSCode,
HTMLCode: req.body.HTMLCode,
CSSCode: req.body.CSSCode,
screenshot: req.file.buffer,
});
await newElement.save();
res.send("Data uploaded successfully!");
} catch (e) {
console.error(e);
}
});
Server.js
const express = require("express");
const passport = require("passport");
const session = require("express-session");
const cors = require('cors');
const elementRouter = require("./routes/elementRoute");
const authRouter = require("./routes/authRoute");
const connectDB = require("./config/db");
const app = express();
const port = process.env.PORT || 5000;
connectDB();
app.use(
session({
secret: "googleOAuth",
resave: false,
saveUninitialized: true,
})
);
app.use(cors());
// Passport Config
require("./config/passport")(passport);
app.use(passport.initialize());
app.use(passport.session());
app.use("/api/elements", elementRouter);
app.use("/api/auth", authRouter);
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
You need to install and require body-parser in your serverside code
First run npm i --save body-parser
Then require it like this
const bodyParser = require("body-parser");
Then use it after you declare your app ( after this line const app = express();)
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
This makes the data of your request available in req.body
Is there a way to intercept a http call before the csurf validation. I have the below code
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// create api router
var api = createApiRouter()
// mount api before csrf is appended to the app stack
app.use('/api', api)
// now add csrf and other middlewares, after the "/api" was mounted
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))
app.get('/form', function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', function (req, res) {
res.send('csrf was required to get here')
})
function createApiRouter () {
var router = new express.Router()
router.post('/getProfile', function (req, res) {
res.send('no csrf to get here')
})
return router
}
I want to log the CSRF token sent by the client for troubleshooting an error I am getting. But I was not able to find a way to intercept the request before it is sent for CSRF validation.
I was able to do it by adding the following code
var logToken = function (req, res, next) {
console.log('Token: ', res.get('x-xsrf-token');
next();
};
app.use(logToken);
I added this code before configuring the csrf token and after configuring the cookie parser.
I am trying to set up neo4j databace to use with javescript code.
When I run my code, I keep getting this
PS C:\Users\futur\Documents\Coding\Neo4j> node app.js body-parser
deprecated undefined extended: provide extended option app.js:21:20
Server has started GET / 304 37.114 ms - - { Neo4jError: getaddrinfo
ENOTFOUND locthost locthost:7687
at captureStacktrace (C:\Users\futur\Documents\Coding\Neo4j\node_modules\neo4j-driver\lib\v1\result.js:200:15)
at new Result (C:\Users\futur\Documents\Coding\Neo4j\node_modules\neo4j-driver\lib\v1\result.js:73:19)
at Session._run (C:\Users\futur\Documents\Coding\Neo4j\node_modules\neo4j-driver\lib\v1\session.js:122:14)
at Session.run (C:\Users\futur\Documents\Coding\Neo4j\node_modules\neo4j-driver\lib\v1\session.js:101:19)
at C:\Users\futur\Documents\Coding\Neo4j\app.js:31:4
at Layer.handle [as handle_request] (C:\Users\futur\Documents\Coding\Neo4j\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\futur\Documents\Coding\Neo4j\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\futur\Documents\Coding\Neo4j\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\futur\Documents\Coding\Neo4j\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\futur\Documents\Coding\Neo4j\node_modules\express\lib\router\index.js:281:22
code: 'ServiceUnavailable', name: 'Neo4jError' }
Here is what my code looks like
var express = require("express");
var path = require("path");
var logger = require("morgan");
// var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var neo4j = require("neo4j-driver").v1;
var app = express();
//
// <script src="lib/browser/neo4j-web.min.js"></script>
//view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extened: false}));
// app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
var driver = neo4j.driver("bolt://locthost", neo4j.auth.basic("neo4j", "test"));
var session = driver.session();
//home route
app.get('/', function(req, res){
session
.run("MATCH (n) RETURN n")
.then(function(result){
result.records.forEach(function(records){
console.log(records._fields[0]);
});
})
.catch(function(error){
console.log(error);
});
res.render("index");
});
app.listen(3000);
console.log('Server has started');
module.export = app;
What do I need to do?
You may have a typo in your bolt URI.
If your code is running on the same machine as the neo4j server, try changing locthost to localhost.