I currently have a React App (via create-react-app
) and an Express server for my API calls. They are both running separately and have been working fine until I ran into this problem:
I'm also using express-session
and passport
for user authentication. I'm able to authenticate users but the session doesn't persist between API calls. If I successfully login, the next time I make an API call, req.sessionID
will be different, and req.isAuthenticated()
will return false
.
Here is my server code:
'use strict'
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var cors = require('cors');
var flash = require('connect-flash');
var store = require('./store');
var database = require('./database');
var app = express();
var port = process.env.port || 3001;
var router = express.Router();
var promise = mongoose.connect('mongodb://localhost:27017/lifeless-db', {useMongoClient: true});
//app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser('lifeless-secret-01890'));
app.use(session({
secret: 'lifeless-secret-01890',
saveUninitialized: true,
cookie: {
secure: false,
}
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
// Initialize Passport
var authinit = require('./auth/init');
authinit(passport);
// For debugging:
app.use(function(req, res, next) {
console.log("SessionID: " + req.sessionID);
console.log(req.isAuthenticated() ? "This user is logged in" : "This user is NOT logged in");
next();
});
// GET
app.get('/items', function(req, res) {
store.getAllItems((items) => {
if(!items) return res.send({error: true, message: 'Error loading store :/', items: null});
else return res.send({error: false, message: 'Success', items: items});
});
});
app.get('/login', function(req, res) {
console.log(req.flash());
console.log("Login fail");
res.send({error: true, message: 'Unknown error'});
});
// POST
app.post('/message', function(req, res) {
database.submitMessage(req.body.email, req.body.message, (success) => {
if (success) return res.send({error: false, message: 'Success'});
else return res.send({error: true, message: 'Error sending message'});
});
});
app.post('/login', passport.authenticate('local', {failureRedirect: '/login', failureFlash: true}), function(req, res) {
console.log(req.flash());
console.log("Login success");
return res.send({error: false, message: 'Success'});
});
// SERVER
app.listen(port, function(){
console.log('Server started.');
console.log('Listening on port ' + port);
});
And here is an example of an API call from the React App (using axios
):
login(e) {
e.preventDefault();
axios({
method: 'post',
url: 'http://localhost:3001/login',
data: {
username: this.state.username,
password: this.state.password,
}
})
.then((response) => {
console.log(response.data);
if (response.data.error) {
this.setState({error: true, errmessage: response.data.message});
} else {
this.setState({redirect: true});
}
})
.catch((error) => {
this.setState({error: true, errmessage: 'Error logging in'});
});
}
I figure there must be some way to have React store the session somehow (?) but I'm fairly new to React and don't really know how to use it with an express backend.
In every React project, we manage data on the client through state and user interactions. However, many apps are not possible without data that comes from the backend. The backend takes care of getting or updating data in our application and it is hidden away from the user.
NodeJS. NodeJS is considered a perfect backend partner of React JS because of its great compatible features. Both front-end and backend libraries use the same JavaScript language that enables them to develop modern applications.
export default App; Now run the Nodejs process npm run dev in one terminal and in another terminal start Reactjs using npm start simultaneously. Output: We see react output we see a button “Connect” we have to click it. Now when we see the console server-side we see that the ReactJS is connected with NodeJS.
Your axios request from your React client needs to be sent withCredentials. To fix it, either do axios.defaults.withCredentials = true;
or do axios.get('url', {withCredentials: true})...
Also in your expressjs backend, set cors options credentials: true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With