'session changes are losing when request ends in react and nodejs
Hi am trying to implement authentication using node js sessions in file mainLoginArea.js i am calling a function goButtonClicked which helps user to sign in by calling an api from http://localhost:4000/app/panel/articleverification/signin after getting results from this api , am checking wheather session has new values isAuthenticated and aid if session has means user has successfully signed in. Then after sigining in am redirecting to different react page using the help of react router, on this new page i have added a middle ware which check wheather req.session.isAuthenticated and req.session.aid are there are not if they exist then i simply redirect new page without any error otherwise an alert with generate on new page Failed: you are not authorized! but what the issue i am facing is even after successfull signin i am getting the same alert (means newly added values to session are getting lost). for convenience i am adding neccessary code also. Please help how can i resolve this.
here is my mainLoginArea.js in react
import react from "react";
import "../../../../css/panel/articleverificationpanel/topmostTray.css";
import axios from "axios";
import { useNavigate,Navigate } from 'react-router-dom'
class MainLoginAreaForPanel extends react.Component {
goButtonClicked =() => {
try {
const userId = document.getElementById("userId").value;
const password = document.getElementById("password").value;
const securityKey = document.getElementById("securityKey").value;
const data = {
userId,
password,
securityKey,
};
axios
.post(
`http://localhost:4000/app/panel/articleverification/signin`,
data,
{ withCredentials:true , credentials: 'same-origin'},
)
.then(async (res) => {
// means file has been uploaded
if (res.data.success === 1) {
let uid;
if(res.data.data.uid){
uid = res.data.data.uid
} else {
uid = parseInt(userId)
}
console.log('Auth',res.data)
this.props.authorizeUser(true,uid)
// session changes are getting lost here
this.props.navigation('/panel/articleverification/homepage')
} else {
alert(res.data.message);
}
})
.catch((error) => {
alert(`${error.message}677`);
});
} catch (error) {
alert(`${error.message}7894`);
}
}
render() {
return (
<react.Fragment>
<div id="mainLoginPanelArea">
<label htmlFor="userId" className="children">
User id:
</label>
{" "}
<input type="text" id="userId" name="userId" className="children" />
<br />
<br />
<label htmlFor="password">Password:</label>
{" "}
<input type="text" id="password" name="password" />
<br />
<br />
<label htmlFor="securityKey">Security Key:</label>
{" "}
<input type="text" id="securityKey" name="securityKey" />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<button className="btn" onClick={this.goButtonClicked}>
GO
</button>
</div>
</react.Fragment>
);
}
}
// Wrap and export
export default function(props) {
const navigation = useNavigate();
return <MainLoginAreaForPanel {...props} navigation={navigation} />;
}
here is the function (of backend (nodejs)) which logs the user in
const signIn = async (req, res) => {
const { userId, password, securitykey } = req.body;
try {
if(req.cookies.avPSess){
const sess = JSON.parse(req.cookies.avPSess)
getDataFromSessionId(sess.sessId).then((data)=>{
const cookieData = JSON.parse(data.data.data[0].data)
console.log(req.session.id,657)
req.session['isAuthenticated']=cookieData.isAuthenticated
req.session['aid']=cookieData.aid
req.session.save(function(err){
if(err){
console.log(err)
}
else{
console.log('no error in resaving session')
}
})
console.log(req.session,774)
res.status(200).send(resultObject(1,`Success: success fully logged you in`,{uid:cookieData.aid,req: req.session}))
}).catch((data)=>{
console.log(data,543442)
res.send(resultObject(0,`Failed: we can't log you in right now please wait for atleast 1.5 hr`,{}))
})
} else {
if (!req.session)
throw new Error("Failed: your session has not setup properly");
checkIfAdminExist(userId, password)
.then((data) => {
req.session.isAuthenticated = true;
req.session.aid = data.data.adminId;
req.session.save()
res.status(202).cookie('avPSess',JSON.stringify({sessId:req.sessionID}),{
sameSite:'strict',
expires: new Date(new Date().getTime()+60*60*1000),
httpOnly: false,
path:'/'
}).send(data);
})
.catch((data) => {
console.log(data);
res.send(data);
});
}
} catch (error) {
writeErrToFileForArticleVerificationPanel({
when: `unable to log in admin his admin id was ${userId}`,
where: "signIn() for article verification panel",
error: `${error.message} here stack was ${error.stack}`,
});
res.send(resultObject(0,"Failed: could not sign in you now try after sometime",{}));
}
};
here is the app.js of backend part
const express = require("express");
const cors = require('cors')
const cookieParser=require('cookie-parser')
const mysql = require('mysql')
const path = require("path");
const { firebase, firebaseConfig } = require("./utils/firebaseStuff")
firebase.initializeApp(firebaseConfig)
const config = require("./config/production.json")
const session = require("express-session");
const mysqlStore = require('express-mysql-session')(session);
const sessionConnection = mysql.createConnection(config.Session.options)
const app = express();
app.use(cors({ origin:['http://localhost:3000','http://localhost:3000/'],credentials:true}))
app.use(cookieParser())
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const publicDirectoryPath = path.join(__dirname, "/public");
app.use(express.static(publicDirectoryPath));
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"
);
next();
});
let sessionOptions = config.Session.options
sessionOptions['createDatabaseTable']=false
sessionOptions['schema']=config.Session.schema
const sessionStore = new mysqlStore(sessionOptions,sessionConnection);
// app.set('trust proxy', 1)
app.use(
session({
name:'sid',
resave: false,
secret: "appSecretSessionTextP2p2r421412412",
cookie: {
sameSite:'strict',
maxAge: 1000*60*60,
secure: false
},
rolling:true,
store: sessionStore,
saveUninitialized: false,
})
);
app.set("view engine", "ejs");
const port = process.env.PORT || 4000;
app.use("/app", require("./routes"));
app.get("/", (req, res) => {
res.render("entryPage");
});
app.listen(port, () => {
console.log(`Server is running on ${port}`);
});
and this the middleware which checks for authentication
const { app } = require("firebase-admin");
const {resultObject} = require('../utils/commonUtils')
function isAuthorizeForAvPanel (req, res, next) {
console.log(req.session,645,req.session.id)
if(req.session.isAuthenticated && req.session.aid){
console.log('you are authorized')
next();
} else {
return res.send(resultObject(0,'Failed: you are not authorized!',{}))
}
};
module.exports = {
isAuthorizeForAvPanel,
};
and finally this is how i am using react react router in app.js frontend side
import React from "react";
import {Routes,Route} from 'react-router-dom'
import EditorPage from './components/editor/classbased/editorPage'
import LoginPageForArticalVerificationPanel from './components/panel/articleverficationpanel/classbased/loginPage'
import HomePageForArticalVerificationPanel from './components/panel/articleverficationpanel/classbased/homePage'
import ArticlePageForArticalVerificationPanel from './components/panel/articleverficationpanel/classbased/articlePage'
class App extends React.Component {
state = {
authorised: JSON.parse(localStorage.getItem("authorized")) ?? false,
adminId: parseInt(JSON.parse(localStorage.getItem("adminId"))) ?? undefined,
extras:{}
}
componentDidUpdate(prevProps, prevState) {
// Persist authorized state changes to localStorage
if (prevState.authroised !== this.state.authorised) {
console.log('changed')
localStorage.setItem("authorized", JSON.stringify(this.state.authorised));
localStorage.setItem("adminId", JSON.stringify(this.state.adminId));
}
}
authorizeUser = (authorizeState,adminId) => {
console.log(adminId,5633)
console.log('called 1')
this.setState({
authorised:authorizeState,
adminId:adminId
})
}
render() {
return (
<>
<Routes>
<Route path='/editor' element={<EditorPage />} />
<Route path='/panel/articleverification' element={<LoginPageForArticalVerificationPanel authorizeUser={this.authorizeUser}/>} />
<Route path='/panel/articleverification/homepage' element={<HomePageForArticalVerificationPanel authorized={this.state.authorised}/>} />
<Route path='/panel/articleverification/articlepage' element={<ArticlePageForArticalVerificationPanel authorized={this.state.authorised} adminId={this.state.adminId}/>} />
</Routes>
</>
);
}
}
export default App;
Lastly here is how i have added middleware for different routes
const router = require('express').Router();
const {isAuthorizeForAvPanel} = require('../middlewares/articleVerificationPanelMiddleware')
let { signIn, getUnverfiedArticles,getUnverfiedArticledata,resendArticleToContributor, discardArticleOfContributor , publishArticle} = require("../controllers/articleVerificationPanelController")
router.post('/signin',signIn);
router.get('/getunverifiedarticles',isAuthorizeForAvPanel, getUnverfiedArticles)
router.post('/articledata',isAuthorizeForAvPanel, getUnverfiedArticledata)
router.post('/publisharticle',isAuthorizeForAvPanel, publishArticle),
router.post('/resendarticle',isAuthorizeForAvPanel, resendArticleToContributor),
router.post('/discardarticle',isAuthorizeForAvPanel,discardArticleOfContributor)
module.exports = router
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
