I'm doing clienten post operation on my node js server, it works fine from postman, but clienten undefend returns
as i said from postman
{ "user": {
"email": "levlaaaaa#levla.com",
"password": "123" } }
When I throw the object, it works fine, but it returns undefined on the cilient side.
client request file (react)
const loginProccsess = async (e) => {
e.preventDefault()
const data = {
"user": {
"email":email,
"password": password
}
}
// return console.log(JSON.stringify(data))
await fetch("/api/auth/login", {
method: "POST",
mode: "cors",
// credentials: "some-origin",
header: {
"Content-type ": "application/json"
},
redirect: "follow",
body: JSON.stringify(data)
}).then((res) => {
console.log(res)
})
backend login.js (login router request)
router.post("/login", authOP, (req, res, next) => {
const { body: { user } } = req
const userLogin = new User();
console.log(user)
if (!user.email && !user.password) {
return res.status(402).json({
errors: "Eposta veya şifre zorunlu 😊 ! ",
});
}
return passport.authenticate('local', {
session: false,
successRedirect: '/home',
failureRedirect: '/login'
}, (err, passportUser, info) => {
if (err) {
return next(err)
}
if (passportUser) {
console.log(passportUser)
const user = passportUser
user.token = userLogin.generateJWT(user.email, user.id);
return res.json({ user: passportUser })
}
return res.status(400).json({ message: info });
})(req, res, next)
})
// app.js(server) (main file)
app.use(Sentry.Handlers.requestHandler());
app.use(cookieParser());
app.use(express.json())
app.use(cors());
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'secret'
}))
app.use(passport.initialize())
app.use(passport.session())
Related
I am sending an auth request from chrome to my backend, there is payload chrome developer tool, it seems to have received the object, but I am backend
or: Cannot read properties of undefined (reading 'email')
It gives an error, I printed req.body from the console, it is empty object, what can I do?
backend
postmande works fine and logs in successfully
const { body: { user } } = req
console.log(req.body)
const userLogin = new User();
if (!user.email && !user.password) {
return res.status(402).json({
errors: "Eposta veya şifre zorunlu 😊 ! ",
});
}
return passport.authenticate('local', {
session: false,
successRedirect: '/home',
failureRedirect: '/login'
}, (err, passportUser, info) => {
if (err) {
return next(err)
}
if (passportUser) {
console.log(passportUser)
const user = passportUser
user.token = userLogin.generateJWT(user.email, user.id);
return res.json({ user: passportUser })
}
return res.status(400).json({ message: info });
})(req, res, next)
react fetch (client)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
// const token = localStorage.getItem("X-CSRF-TOKEN");
const loginProccsess = async (e) => {
e.preventDefault()
const data = {
"user": {
email,
password
}
}
fetch("/api/auth/login", {
method: "POST",
mode: "cors",
// credentials: "some-origin",
header: {
"Content-type ": "application/json"
},
redirect: "follow",
body: JSON.stringify(data)
}).then((res) => {
console.log(res)
})
.catch(err => console.log(err))
}
I'm using express-jwt in my project but I'm getting this error, I couldn't find the solution
import jwt from "express-jwt";
const getTokenFromHeaders = (req) => {
const { headers: { authorization } } = req
if (authorization && authorization.spilt(' ')[0] === 'Token') {
return authorization.split(' ')[1]
}
return null
}
const auth = {
required: jwt({
secret: " /\-l/\Y",
userProperty: 'payload',
getToken: getTokenFromHeaders
}),
optional: jwt({
secret: "/\-l/\Y",
userProperty: 'payload',
getToken: getTokenFromHeaders,
credentialsRequired: false,
})
}
export default auth
this use
router.post("/login", auth.optinal, (req, res, next) => {
const { body: { user } } = req
if (!user.email && !user.password) {
return res.status(402).json({
errors: "Eposta veya şifre yanlış ! ",
});
return passport.authenticate('local', { session: false }, (err, passportUser, info)
=> {
if (err) {
return next(err)
}
if (passportUser) {
const user = passportUser
user.token = passportUser.genareteJWT();
return res.json({ user: user.toAuthJSON() })
}
return res.status(400).info;
})(req, res, next)
}
})
and error message:
required: jwt({
^
TypeError: jwt is not a function
at file:///C:/Users/atala/Desktop/atalayapp-main/backend/middleware/auth/auth.js:12:15
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:61:12)
I read a lot of questions like this but no one is usefull for me.
I have a MERN app. I use Heroku to deploy. In my local environent everithing works but in heroku the login crash. I use Cookies. and try every posible configuration.
Please help.
This is my login server:
login: async (req, res) => {
try {
const { email, password } = req.body;
const user = await Users.findOne({ email })
//console.log(user)
if (!user) return res.status(400).json({ msg: "Usuario inexistente" })
const isMatch = await bcrypt.compare(password, user.password)
if (!isMatch) return res.status(400).json({ msg: "Clave erronea" })
//If login success, craete access Token and refresh
const accesstoken = createAccessToken({ id: user._id })
const refreshtoken = createRefreshToken({ id: user._id })
//console.log(refreshtoken)
res.cookie('refreshtoken', refreshtoken, {
sameSite: 'strict',
httpOnly: true,
path: '/user/refresh_token',
maxAge: 7 * 24 * 60 * 60 * 1000 //7days
})
res.json({ accesstoken })
} catch (err) {
return res.status(500).json({ msg: err.message })
}
},
Here server conf.
//MIDDELEWARES
app.use(express.json())
app.use(cookieParser())
//app.use(cors())
/*app.use(cors({
credentials: true,
origin: 'https://gabymanualidades.herokuapp.com/'
}))*/
app.use(cors({origin: 'https://*****.herokuapp.com', methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'], credentials: true, headers: 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method' }))
app.use(fileUpload({
useTempFiles: true
}))
And client:
const loginSubmit = async e => {
e.preventDefault()
try {
//await axios.post('/user/login', { ...user })
const res=await axios.post('/user/login', { ...user }, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true,
baseURL: "*****.herokuapp.com"
})
console.log(res)
localStorage.setItem('firstLogin', true)
//window.location.href = "/products";
} catch (err) {
alert(err.response.data.msg)
}
}
Thak you very much!
Screenshot:
It is as if I logged in without saving the cookie since then I can't get it again here:
useEffect(() => {
const firstLogin = localStorage.getItem('firstLogin')
if (firstLogin) refreshToken()
}, [])
const refreshToken = async () => {
try {
console.log("aca problema")
const res = await axios.get('/user/refresh_token', {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true,
baseURL: "https://young-wildwood-03509.herokuapp.com/"
})
setToken(res.data.accesstoken)
setTimeout(() => {
refreshToken()
}, 10 * 60 * 1000)
} catch (err) {
alert(err.response.data.msg)
}
}
Server:
refreshToken: (req, res) => {
try {
//console.log(req.cookies)
const rf_token = req.cookies.refreshtoken;
if (!rf_token) return res.status(401).json({ msg: "Plase Login or registeer" })
jwt.verify(rf_token, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
if (err) return res.status(400).json({ msg: "Plase Login or registerr" })
const accesstoken = createAccessToken({ id: user.id })
//res.json({user, accesstoken})
console.log({ accesstoken })
res.json({ accesstoken })
})
//res.json({ rf_token })
} catch (err) {
return res.status(500).json({ msg: err.message })
}
},
When I make a fetch request from my react frontend to login using passport.authenticate('./local), my passport.serializeUser is called but passport.deserializeUser is NOT (and req.user is not set).
I've read as many answers to this question on stackoverflow but to no avail. Here is my code below.
All this comes before my routes on the server.js:
//Express body parser
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.json());
//Express Session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: {
secure: false
}
}));
// Passport config
require('./config/passport')(passport);
//Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
Here is the passport config file:
module.exports = function(passport) {
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, async function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
const match = await bcrypt.compare(password, user.password);
if (!match) { return done(null, false); }
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
console.log('this gets called logged)
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log('this does NOT GET LOGGED');
User.findById(id, function(err, user) {
done(err, user);
});
});
};
Here is the react fetch request for the login route:
fetch('http://localhost:5000/authentication/login', {
method: 'POST',
body: JSON.stringify(this.state.formData),
headers: {"Content-Type": "application/json"},
mode: 'cors'
})
.then(res => res.json())
.then(resObject => {
if (resObject.errors) {
console.log('errors')
} else {
this.props.dispatch(handleLoginuser(resObject.user))
this.setState({
redirect: true
})
}
});
Here is the fetch request for another random route that should be protected:
componentDidMount() {
fetch('http://localhost:5000/protectedroute', {
method: 'GET',
mode: 'cors',
credentials: 'include'
})
.then(res => res.json())
.then(resObject => {
if(resObject.loggedIn) {
this.setState({
loggedIn: true
})
}
});
}
Here are the login and protected routes:
app.post('/authentication/login', passport.authenticate('local'), (req, res) => {
res.json({errors: false, user: req.user})
});
app.route('/protected')
.get(function(req, res) {
//req.user will be undefined!
if (req.user) {
return res.json({loggedIn: true})
} else {
return res.json({loggedIn: false})
}
})
I believe it's because of your post/login route on the back end.
Calling the passport.authenticate middleware does not complete the login process unless you use the boilerplate code from the official docs (which does not work with React)
You need to call req.login to complete the login process. Check out this example
app.post('/authentication/login', (req, res, next) => {
passport.authenticate('local', (err, theUser, failureDetails) => {
if (err) {
res.status(500).json({ message: 'Something went wrong authenticating user' });
return;
}
if (!theUser) {
res.status(401).json(failureDetails);
return;
}
// save user in session
req.login(theUser, (err) => {
if (err) {
res.status(500).json({ message: 'Session save went bad.' });
return;
}
console.log('---123456789098765432345678---', req.user);
res.status(200).json({{errors: false, user: theUser}});
});
})(req, res, next);
});
Setting up withCredentials: true while sending the post request worked for me.
axios.post(uri, {
email: email,
password: password
}, {
withCredentials: true
})
I'm having trouble understanding how to send back a refresh token to get a new access token.
I've looked at this documentation: https://developer.microsoft.com/en-us/graph/docs/concepts/nodejs and I basically need help with Authenticate User- step4 but they don't seem to go into more details.
I tried using passport-oauth2-refresh but I think because I'm using Azure AD, I kept getting Error: Cannot register: not an OAuth2 strategy. So I've decided to try to manually check the expiry instead.
I am able to retrieve a refresh token (POST /token with req.user.refreshToken) along with my access token and I store it in json but I don't know how to send it back.
Here is my index.js:
const express = require('express');
const router = express.Router();
const graphHelper = require('../utils/graphHelper.js');
const passport = require('passport');
const request = require('request');
const SERVER = process.env.SERVER;
let user_id = null;
router.get('/', (req, res) => {
if (!req.isAuthenticated()) {
res.render('login');
} else {
renderBotPage(req, res);
}
});
router.get('/login',
passport.authenticate('azuread-openidconnect', {failureRedirect: '/'}),
(req, res) => {
res.redirect('/');
});
router.get('/token',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res, // required
failureRedirect: '/'
}
)
},
function (req, res) {
const options = {
headers: {
'content-type' : 'application/json'
},
method: 'POST',
url: SERVER,
json: {
'accessToken': req.user.accessToken,
'refreshToken': req.user.refreshToken
}
};
request(options,
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body)
}
}
);
console.log('We received a return from AzureAD get token.');
res.redirect('/');
});
router.post('/token',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res, // required
failureRedirect: '/'
}
)(req, res, next);
},
function (req, res) {
console.log('res after first token function', res);
const options = {
headers: {
'content-type' : 'application/json'
},
method: 'POST',
url: SERVER,
json: {
'accessToken': req.user.accessToken,
'refreshToken': req.user.refreshToken
}
};
request(options,
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body)
}
}
);
res.redirect('/');
});
function renderBotPage(req, res) {
graphHelper.getUserData(req.user.accessToken, (err, user) => {
if (!err) {
res.render('chatbotOn', {
display_name: user.body.displayName,
user_id:user.body.id
});
} else {
// Catch of Expired token error
if (hasAccessTokenExpired(err)) {
req.session.destroy(() => {
req.logOut();
res.clearCookie('graphNodeCookie');
res.status(200);
res.redirect('/');
});
}
renderError(err, res);
res.render('chatbotOn', {
display_name: "Random User"
});
}
});
}
router.get('/disconnect', (req, res) => {
req.session.destroy(() => {
req.logOut();
res.clearCookie('graphNodeCookie');
res.status(200);
res.redirect('/');
});
});
function hasAccessTokenExpired(e) {
let expired;
if (!e.innerError) {
expired = false;
} else {
expired = e.forbidden &&
e.message === 'InvalidAuthenticationToken' &&
e.response.error.message === "Le token d'accès a expiré.";
}
return expired;
}
function renderError(e, res) {
e.innerError = (e.response) ? e.response.text : '';
res.render('error', {
error: e
});
}
module.exports = router;
My app.js
const callback = (iss, sub, profile, accessToken, refreshToken, done) => {
done(null, {
profile,
accessToken,
refreshToken
});
};
passport.use(new OIDCStrategy(config.creds, callback));
And here is my graphHelper.js:
const request = require('superagent');
function getUserData(accessToken, callback) {
request
.get('https://graph.microsoft.com/beta/me')
.set('Authorization', 'Bearer ' + accessToken)
.end((err, res) => {
callback(err, res);
});
}
exports.getUserData = getUserData;
here is my config.js:
module.exports = {
creds: {
redirectUrl: 'http://localhost:3000/token',
clientID: 'xxxxx', // regular
clientSecret: 'xxxxx', // regular
identityMetadata:
'xxxxxx',
allowHttpForRedirectUrl: true, // For development only
responseType: 'code id_token',
validateIssuer: false, // For development only
responseMode: 'form_post',
scope: ['openid', 'offline_access', 'Contacts.Read',
'Calendars.ReadWrite'
]
},
};