cookie doesn't get sent on first request - javascript

I've got the following code on my server.js express application:
var express = require('express');
var fallback = require('express-history-api-fallback');
var compress = require('compression');
var favicon = require('serve-favicon');
var prerenderio = require('prerender-node');
var config = require('getconfig');
var app = express();
app.use(function (req, res, next) {
if (config.environment !== 'local') {
res.cookie('config', JSON.stringify(config), { secure: true });
}
else {
res.cookie('config', JSON.stringify(config));
}
next();
});
app.get('/versioncheck', function(req, res) {
return res.json({ version: config.version });
});
app.use(compress());
app.use(prerenderio.set('prerenderToken', config.prerender_token).set('protocol', 'https'));
app.use(express.static(__dirname, { maxAge: 31536000 }));
app.use(favicon(__dirname + '/favicon.ico'));
app.use(fallback('index.html', { root: __dirname }));
const PORT = process.env.PORT || 1010;
app.listen(PORT, function () {
console.log('Server started on port %s', PORT);
});
The first middleware I'm setting up with express is quite simple: It sends down a cookie to the client with some config information. The issue I'm facing is that this cookie doesn't get sent down to the client upon first request. For all subsequent requests it does work fine. What am I missing?

I had a similar problem some time ago.
At the begin of the first request, the cookie does not exist.
The cookies get sent during the request, not before.
So, at the begin of the second request, the cookie is set (from request 1).

Related

couldn't get the cookie nodejs

I set a cookie with,
router.get("/addCartToCookie", function(req, res) {
let options = {
maxAge: 1000 * 60 * 15,
httpOnly: true,
};
let cartData = {
name: "test cookie",
slug: slugify("test cookie"),
productPictures: "K6B4dzGjN-teal.jpeg",
price: 200,
description: "testing cookies",
quantity: 7,
};
// Set cookie
res.cookie("cartName", cartData, options);
res.send("Cart Added to Cookie");
});
Which perfectly sets a cookie named "cartName". But once I try to get the cookie,
It shows "cartName" is undefined.
Get Cookie Code:
router.get("/getCartFromCookie", function (req, res) {
res.send(req.cookies["cartName"]);
console.log(req.cookies);
});
I tried console logging the cookies but it also shows undefined.
From what I know, the optimized way of handling cookies is by using cookie-parser dependency for express.
$ npm install cookie-parser
Then you could easily fetch your cookies using req.cookies or req.signedCookies property like below:
var express = require('express')
var cookieParser = require('cookie-parser')
var app = express()
app.use(cookieParser())
app.get('/', function (req, res) {
// Cookies that have not been signed
console.log('Cookies: ', req.cookies)
// Cookies that have been signed
console.log('Signed Cookies: ', req.signedCookies)
// Your cart cookie
console.log('Cookies: ', req.cookies.cartName)
})
app.listen(8080);
References:
https://github.com/expressjs/cookie-parser
http://expressjs.com/en/resources/middleware/cookie-parser.html
You don't show all your code, but I assume you're using the cookie-parser middleware to access the cookies directly on the request object. If not, start by adding cookie-parser and go from there.
For your cookie reading issue, be aware that you can't send and read cookies on the same request. You need one request to set the cookie and another to read the cookie.
import express from 'express';
import cookieParser from 'cookie-parser'
import {inspect} from 'util';
const app = express();
const router = express.Router()
router.use(cookieParser())
app.use(router);
const port = 3000
router.get('/setcookie', (req, res) =>{
res.cookie('testCookie', 'magic content');
res.send("set the cookie");
})
router.get('/readCookie', (req, res) =>{
res.send('your cookies: ' + inspect(req.cookies['testCookie']));
console.log(req.cookies);
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})

node.js server can't receive any calls unless an empty folder is created on the server

I'm probably doing something silly, and putting myself in a situation that I don't need to be in. But my ultimate question is why do I have to have an empty folder in my server in order for my GET requests to work?
Before I start with an example, everything is under a subfolder: http://www.example.org/subfolder1
Here is Server code:
const express = require('express');
const datastore = require('nedb');
const url = require("url");
var path = require('path');
const app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server,
{
path: '/subfolder1/socket.io',
cors:
{
origin: '*',
methods: ["GET", "POST"],
credentials: true
}
});
const port = 3000;
io.on('connection', socket => {
console.log("Socket connected: " + socket.id);
});
app.get("/subfolder1/getSettings", (req, res, next) => {
res.json({ configuration: conf });
});
app.use(express.json());
app.get("/subfolder1/", function (req, res) {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.use(express.static(path.join(__dirname, 'public')));
server.listen(port, '0.0.0.0', function(error){
if(error) {
console.log('Server failed to listen: ', error)
} else{
console.log('Server is listening on port: ' + port)
}
});
client code:
const response = await fetch("/subfolder1/getSettings");
const settings = await response.json();
Now, in this example I'm calling getSettings (http://www.example.org/subfolder1/getSettings):
app.get("/subfolder1/getSettings", (req, res, next) => {
res.json({ configuration: conf });
});
No matter what I do, I will forever get a 404 error message unless I create an empty folder called "getSettings" in my folder structure on my server. Once I create the empty folder, the call works! So for now, I've just making empty folders on my server for my get calls. Well now look what happens when the URL is something more complicated, such as the following:
http://www.example.org/subfolder1/team=6/queuedPlayers (Where team can be any integer)
Now I'm stuck and my workaround is broken. Any ideas?

req.session undefined for express app (using Okta middleware) in chrome but not safari

There are similar questions out there, but not that directly address why this application of express-session consistently works in Safari but not in chrome.
My server code is below, which only needs to authenticate a single page with a logged out and logged in view. Yesterday, this was working in chrome when served locally and when deployed to Azure or Heroku. Today, with no change made, it wasn't working at all in chrome, both locally or deployed. The home page load but when I click login and am redirected to the Okta login page, this is the error I am getting after logging in when redirected back to my page (e.g. localhost:3000/authorization-code/callback?code=xxxxxxxx&state=xxxxxxxx) after logging in:
Error: did not find expected authorization request details in session, req.session["oidc:https://subdomain.domain.com/oauth2/default"] is undefined
I then tested in Safari where it has consistently worked without issue--both local and hosted. I did just noticed that the hosted version works in Azure again for the moment--again, with no change or redeployment. The local version still does not work.
const http = require('http')
const express = require('express')
const path = require('path')
const app = express()
const fs = require('fs')
require('dotenv').config()
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.use(express.static('express'))
var cors = require('cors')
const OktaJwtVerifier = require('#okta/jwt-verifier')
const session = require('express-session')
const {
ExpressOIDC
} = require('#okta/oidc-middleware')
var getUserInfo = require('./getUserInfo')
// session support is required to use ExpressOIDC
app.use(
session({
secret: 'secretsecret',
resave: true,
saveUninitialized: false,
cookie: {
httpOnly: false,
},
})
)
const oidc = new ExpressOIDC({
issuer: process.env.ISSUER || 'https://[okta hosted custom domain].com/oauth2/default',
client_id: process.env.CLIENT_ID || 'xxxxxxxxxx',
client_secret: process.env.CLIENT_SECRET || 'xxxxxxxxxxxxxxxxxxx',
redirect_uri: process.env.REDIRECT_URI ||
'http://localhost:3000/authorization-code/callback',
appBaseUrl: process.env.APP_BASE_URL || 'http://localhost:3000',
scope: 'openid profile',
})
// ExpressOIDC attaches handlers for the /login and /authorization-code/callback routes
app.use(oidc.router)
app.use(cors())
app.options('*', cors())
app.get('/userinfo', (req, res) => {
console.debug("in user info")
let domain = 'dev'
if (req.isAuthenticated()) {
getUserInfo.userRequest(res, req.userContext, domain)
}
})
app.get('/authStatus', (req, res) => {
console.debug("in auth status")
if (req.isAuthenticated()) {
res.send(req.userContext.userinfo)
}
})
app.post('/forces-logout', oidc.forceLogoutAndRevoke(), (req, res) => {
// Nothing here will execute, after the redirects the user will end up wherever the `routes.logoutCallback.path` specifies (default `/`)
})
// default URL for website
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/express/index.html'))
//__dirname : It will resolve to your project folder.
})
// FAQ Path
app.get('/help', function(req, res) {
res.sendFile(path.join(__dirname + '/express/help.html'))
//__dirname : It will resolve to your project folder.
})
// default URL for website
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/express/index.html'))
//__dirname : It will resolve to your project folder.
})
const port = normalizePort(process.env.PORT || '3000')
const server = http.createServer(app)
server.listen(port)
console.debug('Info site server listening on port ' + port)
function normalizePort(val) {
var port = parseInt(val, 10)
if (isNaN(port)) {
// named pipe
return val
}
if (port >= 0) {
// port number
return port
}
return false
}

Continuously changing Express Route Paths for protection

I want to create a hidden internal webserver with ever-changing routes.
The aim is to prevent/deter people from scraping the site or using the API without permission.
There's probably a better way (or this could be totally useless)
I've written some code that works but either convince me why I'm wasting my time or why it would work.
const express = require('express');
const uuid = require('uuid/v4');
const app = express();
// These are the hidden routes
const routes = {
hiddenPage: undefined,
};
setInterval(() => {
// Change the path of the hidden page
// every 5 seconds
routes.hiddenPage = `/${uuid()}`;
}, 1000 * 5);
app.get('*', (req, res) => {
// There would be other middleware for
// security reasons
if (req.path === routes.hiddenPage) {
res.send('Welcome to the hidden page');
return;
}
res.send(`Page at <a href=${routes.hiddenPage}>${routes.hiddenPage}</a>`);
});
// Listen on 3000
app.listen(3000);
You can use CORS middleware to allow only specific clients to access your server.
https://expressjs.com/en/resources/middleware/cors.html
Example:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

Passport-cas2 always redirecting to failureRedirect

I'm quite new to Node.js and I'm trying to implement an authentication system through an external CAS server. I'm using Passport.js + passport-cas2 but it's always redirecting me to the failureRedirect page even though the CAS correctly authenticated me. Here is my code:
var SocketIOFileUpload = require('socketio-file-upload'),
socketio = require('socket.io'),
express = require('express'),
path = require('path'),
express = require('express'),
passport = require('passport'),
session = require('express-session'),
bodyParser = require('body-parser');
var CasStrategy = require('passport-cas2').Strategy;
var cas = new CasStrategy({
casURL: 'https://my.cas.server'
},
function(username, profile, done) {
console.log("authenticating");
done(null, new User());
});
var app = express()
.use(bodyParser.urlencoded({ extended: true }))
.use(SocketIOFileUpload.router)
.use(passport.initialize());
passport.use(cas);
app.use(session({ secret: 'my secret phrase' }))
.use(passport.session())
.get('/', function(req, res){
res.redirect('/auth/cas');
})
.get('/auth/cas',
passport.authenticate('cas', { failureRedirect: '/error', successRedirect: '/upload' }),
function(req, res) {
// Successful.
res.redirect('/upload');
})
.use('/upload', function(req, res, next){
if (req.user)
return express.static(path.join(__dirname, 'html'));
else
res.redirect('/auth/cas');
})
.get('/error', function(req, res) {
res.send('Error in authentication. Please Try Again.');
})
.listen(8080, function () {
console.log('Upload Server started on http://localhost:8080');
});
The console.log("authenticating") isn't even executed at all!
Thanks for your help.
Okay, I fixed it, my CAS server certificated was self-signed and I had to edit the passport-cas2 source in order for it to accept the certificate.

Categories