I want to change a session cookie after an asynchronous request but no matter what I tried I keep failing.
My request is as follows:
$.ajax({
type: "POST",
url: "/setStatus",
data: { userId : _userId, token: _token, tokenSecret : _tokenSecret, service : service, loggedIn : _loggedIn, authorized : _authorized },
xhrFields: { withCredentials: true },
crossDomain: true
}).done(function(reply) { alert('finished'); });
Setting the session variables on the server.
exports.setStatus = function(req, res)
{
req.session.userId = req.body.userId;
req.session.token = req.body.token;
req.session.tokenSecret = req.body.tokenSecret;
req.session.service = req.body.service;
req.session.loggedIn = req.body.loggedIn;
req.session.authorized = req.body.authorized;
res.header('Access-Control-Allow-Credentials', 'true');
res.writeHead(200);
};
The setting on the server are as follows:
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'keyboard cat', store: new RedisStore({ host: 'localhost', port: 3000, client: dbcon })}));
app.use(express.methodOverride());
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
I forgot to mention that on simple requests the session cookies change as expected.
Any ideas?
You should call req.session.save() after the modifications if you are doing it with ajax.
exports.setStatus = function(req, res)
{
req.session.userId = req.body.userId;
req.session.token = req.body.token;
req.session.tokenSecret = req.body.tokenSecret;
req.session.service = req.body.service;
req.session.loggedIn = req.body.loggedIn;
req.session.authorized = req.body.authorized;
req.session.save(); // This saves the modifications
res.header('Access-Control-Allow-Credentials', 'true');
res.writeHead(200);
};
Related
I'm doing a login with laravel/sanctum and sveltekit, when I submit the form,first inside the actions I execute first a fetch to the csfr endpoint from sanctum ('/sanctum/csrf-cookie') but in the reponse the cookies are not set automatically in the browser but cookies arrive.So how i can set automatically?
Here the code :
`export const actions: Actions = {
default: async ({ request, fetch, cookies }) => {
const formData = await request.formData();
const user = {
name: formData.get('name'),
email: formData.get('email'),
password: formData.get('password'),
password_confirmation: formData.get('password_confirm')
};
await fetch('http://localhost:8000/sanctum/csrf-cookie', {
method: 'GET',
credentials: 'include'
});
const res = await fetch('http://127.0.0.1:8000/api/register', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
// 'X-XSRF-TOKEN': '' || ''
},
body: JSON.stringify(user)
});
const data = await res.json();
console.log(data);
}
};`
I have the following test
let rxId = "";
let basketAuthToken = "";
let basketId = "";
let replacedBody = "";
cy.fixture(`payload/${ordersPostPayload}`).then((Body) => {
cy.readFile(`temp/resultIdFile.json`).then((resultIdFile) => {
Id = resultIdFile.lastSucceededRxId;
basketAuthToken = resultIdFile.baskets[0].authToken;
basketId = resultIdFile.baskets[0].basketId;
cy.log(`the value of the read value is ${Id}`);
replacedBody = JSON.stringify(Body).split(`$Id`).join(Id);
cy.writeFile(`temp/ordersPostPayload.json`, replacedBody);
cy.request({
method: "POST",
url: `https://***/ops/orders`,
headers: {
"Content-Type": "application/json",
Channel: "**",
"EsbApi-Subscription-Key": `****`,
"Accept-Language": `en-US`,
"basket-token": basketAuthToken,
"basket-id": basketId,
redirectUrl: "****/evaluate-payment",
cancelUrl: "****/evaluate-payment",
},
body: replacedBody,
failOnStatusCode: false,
}).then((response) => {
cy.writeFile("temp/result.json", response);
});
});
});
The request is sent to the backend. On cypress GUI the request is just fired once. but when I check the backend I can see two requests.
I build the project using the mean stack. I insert record using postman but I get one error, I try to resolve much time but not to find where is a mistake.
Postman error
This is models user.js file.which is shows userSchema details.
Models -> user.js
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var config = require('../config/database');
// User Schema
var UserSchema = mongoose.Schema({
name: {
type: String,
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username}
User.findOne(query, callback);
}
module.exports.addUser = function(newUser, callback){
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
newUSer.password = hash;
newUser.save(callback);
});
});
}
This is Routes user.js file. here router of register displays, also define add user status results that can be shown if postman value is inserted in mongo then successfully another wise unsuccessfull message.
Routes -> users.js
var express = require('express');
var router = express.Router();
var password = require('passport');
var jwt = require('jsonwebtoken');
var User = require('../models/user');
// Register
router.post('/register', function(req, res, next){
let newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, user) => {
if(err){
res.json({success: false, msg:'Failed to Register User'});
} else {
res.json({success: true, msg:'User Registered'});
}
});
});
// Authenticate
router.post('/authenticate', function(req, res, next){
res.send('Authenticate');
});
// Profile
router.get('/profile', function(req, res, next){
res.send('Profile');
});
module.exports = router;
You are sending the request wrongly from Postman. You should not use x-www-form-urlencoded. Use the Raw option at send it as a json object, like this:
{
"name": "Mark Melton",
"email": "xyz#gmail.com",
"username": "shuta",
"password": "Sunala123"
}
This is how it will work, because in your routes, you are using req.body...
I want to know why it is so hard to post a simple JSON string in a /:parameter to restify. I have followed many examples but have not found anything concrete.
I have the following code in the front end.
$("#btnDoTest").click(function() {
var jData = {
hello: "world"
};
var request = $.ajax({
url: "http://localhost:8081/j/",
async: false,
type: "POST",
data: JSON.stringify(jData),
contentType: "application/javascript",
dataType: "json"
});
request.success(function(result) {
console.log(result);
});
request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
I am succesful in sending simple text if I concatenate the param after the j/. But what I want to send is an object like this {hello:"world"} and reconstruct it back in nodeJS and work with it.
--Edit:
This is my nodejs file
/* the below function is from restifylib/response.js */
var restify = require("restify");
/* create the restify server */
var server = restify.createServer({
});
server.use(restify.bodyParser({ mapParams: true }));
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
return next();
}
);
server.post('/j/', function (req, res, next) {
//res.send(201,"REceived body: "+JSON.stringify(req.params));
res.send(201,"REceived body: "+JSON.stringify(req.params));
return next();
});
var port = 8081;
server.listen(port);
console.log("Server listening on port " +port)
Any help would be appreciated thanks.
0x
I finally got it working.
--Front end code
$("#btnDoTest").click(function() {
var request = $.ajax({
url: "http://localhost:3000/j",
async: false,
type: "POST",
data: {
blob: {wob:"1",job:"2", ar:[1,2,{a:'b'}]}
},
contentType: "application/x-www-form-urlencoded", //This is what made the difference.
dataType: "json",
});
request.success(function(result) {
console.log(result);
});
request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
NodeJs services
/* the below function is from restifylib/response.js */
var restify = require("restify");
/* create the restify server */
var server = restify.createServer({
});
server.use(restify.bodyParser());
server.use(restify.CORS());
server.post('/j/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
// req.params == data on jquery ajax request.
res.send(200, JSON.stringify(req.params));
console.log(req.params.blob.ar[2].a)
res.end();
return next();
});
var port = 3000;
server.listen(port);
console.log("Server listening on port " + port)
Don't stringify it. Try this, note the two changes, I removed the JSON.stringify and switched to application/json, as its JSON and not JavaScript.
var request = $.ajax({
url: "http://localhost:8081/j/",
async: false,
type: "POST",
data: jData,
contentType: "application/json",
dataType: "json"
});
application/javascript should only be used when doing JSONP.
my answer first!
jquery:
$.ajax({
url: url,
method: 'post',
data: JSON.stringify({key:value}),
contentType: "application/json"
});
node http:
server.post('/1', function(req, res) {
var body = req.body;
var dataValue = body.dataKey;
});
why?
data of $.ajax is just for what to send to server end, its datatype has not be defined, so when use JSON.stringify({key:value}), the data will be sent as a string like '{key:"xxx"}', and node recieve a string, not a json object even the string structure looks like a json. but after we add contentType: "application/json" in $.ajax, when node recieve the data, it will be a real json object type data.
I am currently having a hell of time trying to store sessions in MongoDb.
I've tried express-session-mongo and connect-mongodb and both give me the same "500 internal server error" when I try to load the login page. Which leads me to think maybe there is a conflict with mongoose-auth somewhere.
Anyway here is my setup:
app.js:
var MongoStore = require('connect-mongodb');
var MongoDb = require('mongodb').Db;
var Server = require('mongodb').Server;
var db = new MongoDb('myDb', new Server('localhost', 27017, {auto_reconnect: true, native_parser: false}));
app.configure(function() {
app.use(express.logger({format: 'dev'}));
app.set('views', __dirname + '/../views');
app.set('view engine', 'jade');
app.set('view options', { layout: false });
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(mongooseAuth.middleware());
app.use(require('./mysite').middleware());
app.use(express.methodOverride());
});
app.configure('production', function(){
var oneWeek = 657450000;
app.use(express.static(__dirname + '/../public', { maxAge: oneWeek }));
app.use(express.session({ store: new MongoStore({db: db}), secret: 'super secret' }));
app.use(express.errorHandler());
});
// Routes
require('./routing.js');
mongooseAuth.helpExpress(app);
app.listen(3000);
console.log('Express server listening on port %d in %s mode', app.address().port, app.settings.env);
userModel.js
var Schema = mongoose.Schema;
var mongooseTypes = require("mongoose-types");
var mongooseAuth = require('mongoose-auth');
mongooseTypes.loadTypes(mongoose);
var everyauth = require('everyauth')
everyauth.debug = true;
var UserSchema = new Schema({any: {}});
UserSchema.plugin(mongooseAuth, {
everymodule: {
everyauth: {
User: function () {
return User;
}
}
}
, password: {
loginWith: 'email'
, extraParams: {
phone: String
, username: String
}
, everyauth: {
getLoginPath: '/login'
, postLoginPath: '/login'
, loginView: 'account/login.jade'
, getRegisterPath: '/register'
, postRegisterPath: '/register'
, registerView: 'account/register.jade'
, loginSuccessRedirect: '/login/success'
, registerSuccessRedirect: '/register/success'
}
}
});
mongoose.model('User', UserSchema);
User = mongoose.model('User');
At this moment in time I'm really just trying to use MongoDb as the session store, but again I get a 500 error w/ no information whatsoever in the node.js console when I try to load the login page.
Any help would be greatly appreciated.
Thanks
It ended being a problem of the various modules: connect-session-mongo / express-session-mongo / connect-mongo, using connect 2.0.1 and Express using connect 1.8.5.
Apparently the dependency clash here prevented the session store modules to access the 'req.secret' property.
To make it work I ended using the module connect-mongodb that is still using connect 1.8.5, just like Express.
The reason I couldn't make connect-mongodb work before though was user error, I tried too hard to use copy/paste from online examples instead of my head.
Here is the configuration code that ended up working for me with connect-mongodb:
var Session = require('connect-mongodb');
app.configure('production', function(){
var oneWeek = 657450000;
app.use(express.static(__dirname + '/../public', { maxAge: oneWeek }));
var session = express.session({
store: new Session({
url: 'mongodb://localhost:27017/test',
maxAge: 300000
}),
secret: 'superTopSecret'
});
app.use(session);
app.use(mongooseAuth.middleware());
app.use(require('./mySite').middleware());
app.use(express.methodOverride());
app.use(express.errorHandler());
});
Hope this helps anyone else who runs into this issue. If you have any suggestion/improvement on this solution, I'd be glad to hear it. :)
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser');
const session = require('express-session')
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
mongoose.connect('mongodb://localhost/my-database', {
useMongoClient: true
});
mongoose.Promise = global.Promise;
const db = mongoose.connection
app.use(cookieParser());
app.use(session({
secret: 'my-secret',
resave: false,
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: db })
}));