GraphQl and passport session: access req.user when querying GraphQl - node.js

I have a GraphQl server and a react frontend. I use passport and LocalStrategy to authenticate the user which works well, I can successfully login an existing user. I also want to use passport session to create a user session, so that I can access the logged in user later in my GraphQl resolvers for authentication. I expected passport to set the user in the session after successfully authenticating one. But after sending correct credentials from the client to the server, GraphQl queries do not have access to req.user.
The GraphQL server code looks like this:
import express from 'express';
import passport from 'passport';
import {Strategy as LocalStrategy} from 'passport-local';
import session from 'express-session';
import cors from 'cors';
import bodyParser from 'body-parser';
import models from './models';
import typeDefs from './schema';
import resolvers from './resolvers';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { makeExecutableSchema } from 'graphql-tools';
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
const app = express();
app.use('*', cors({ origin: 'http://localhost:3000' }));
app.set('port', (process.env.PORT || 3001));
//--- Passport ----
app.use(session({
saveUninitialized: true,
resave: false,
secret: 'verysecretsecret'
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
},
function(email, password, done) {
models.User.findOne({
where: {
email: email
}
}).then(function(user) {
if (user) {
if (user.validPassword(password)) {
return done(null, user);
} else {
return done(null, false);
}
}
return done(null, false);
});
}
));
//--- Routes ----
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql'
}));
app.use(
'/graphql',
bodyParser.json(),
graphqlExpress( (req) => {
console.log('/graphql User: ' + req.user); // prints undefined after sending correct login credentials to /login
return ({
schema,
context: {
user: req.user,
},
});}),
);
app.use(bodyParser.urlencoded({ extended: true }) );
app.post('/login', passport.authenticate('local'), (req, res) => {
console.log('/login: User', req.user); // prints the logged in user's data
return res.sendStatus(200);
});
export default app;
And this is the login fetch request from the client:
onSubmit = () => {
var details = {
'email': this.state.email,
'password': this.state.password,
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('http://localhost:3001/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
credentials: 'include',
body: formBody
}).then(function(response) {
console.log(response);
}).catch(function(err) {
// Error
});
};
Do I have to change something on the client side for the server to receive the session cookie? Or is something going wrong in the backend?
I also uploaded a minimal example to this repo: https://github.com/schmitzl/passport-graphql-minimal-example

Managing sessions gets a little messy when you're dealing with CORS. There's a couple of things you need to change to get the behavior you're expecting:
First, modify your server code to ensure you're sending the Access-Control-Allow-Credentials header:
app.use('*', cors({ origin: 'http://localhost:3000', credentials: true }));
Next, make sure your requests are actually including the cookies. You've done so with the login request, by setting the credentials option to include. Apollo uses fetch under the hood and we need to pass this option to it as well.
I may be missing something, but it doesn't appear that apollo-boost provides an easy way to do the above (you have fetchOptions, but including credentials there doesn't appear to do anything). My advise would be to scrap apollo-boost and just use the appropriate libraries directly (or use apollo-client-preset). Then you can pass the appropriate credentials option to HttpLink:
import ApolloClient from 'apollo-client'
import { HttpLink, InMemoryCache } from 'apollo-client-preset'
const client = new ApolloClient({
link: new HttpLink({ uri: apolloUri, credentials: 'include' }),
cache: new InMemoryCache()
})

Related

Why is req.session still undefined when I included session as the top level middleware?

I'm using passport.js for a spotify api application that I'm working on. I want to get the access token from the process.nextTick() function, so I decided to use express-session to get it.
I'm trying to console log req.session to see what it looks like, but it looks like session isn't defined on req: "TypeError: Cannot read properties of undefined (reading 'session')"
Here is the full code:
import session from 'express-session';
import express, { NextFunction, Request, Response } from 'express';
import { ValidateError } from 'tsoa';
import swaggerUi from 'swagger-ui-express';
import * as dotenv from 'dotenv';
import { RegisterRoutes } from '../routes/routes';
import morgan from 'morgan';
import passport, { AuthenticateOptions } from 'passport';
import { VerifyCallback } from 'passport-spotify';
import { Profile } from 'passport-spotify';
import cors from 'cors';
import bodyParser from 'body-parser';
const SpotifyStrategy = require('passport-spotify').Strategy;
// Load environment variables
dotenv.config({ path: '.env' });
const { CLIENT_ID, CLIENT_SECRET } = process.env;
// Augment express-session with a custom SessionData object
type User = {
accessToken?: string;
expires_in?: number;
profile?: Profile;
};
declare module 'express-session' {
interface SessionData {
user: User;
}
}
// Passport Setup
const authCallbackPath = '/callback';
passport.serializeUser((user: object, done: VerifyCallback) => {
done(null, user);
});
passport.deserializeUser((obj: object, done: VerifyCallback) => {
done(null, obj);
});
// Express app setup
export const server = express();
server.use(
session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
}),
);
server.use(bodyParser.urlencoded({ extended: false }));
server.use(bodyParser.json());
server.use(passport.initialize());
server.use(passport.session());
server.use(morgan('combined'));
server.use(cors());
passport.use(
new SpotifyStrategy(
{
clientID: CLIENT_ID,
clientSecret: CLIENT_SECRET,
callbackURL: `http://localhost:3005${authCallbackPath}`,
},
(
_accessToken: string,
_refreshToken: string,
_expires_in: number,
profile: Profile,
done: VerifyCallback,
) => {
process.nextTick(function (req: express.Request) {
// TypeError: Cannot read properties of undefined (reading 'session')
console.log(req.session);
done(null, profile);
});
},
),
);
// Passport endpoints
const authenticateOptions: AuthenticateOptions = {
scope: ['user-read-email', 'user-read-private'],
};
server.get('/passport', passport.authenticate('spotify', authenticateOptions));
server.get(
authCallbackPath,
passport.authenticate('spotify', { failureRedirect: '/login' }),
(_req, res) => {
res.redirect('/');
},
);
// Swagger documentation endpoint
server.use('/docs', swaggerUi.serve, async (_req: Request, res: Response) => {
return res.send(swaggerUi.generateHTML(await import('../../swagger.json')));
});
RegisterRoutes(server);
server.use(function errorHandler(
err: unknown,
req: Request,
res: Response,
next: NextFunction,
): Response | void {
if (err instanceof ValidateError) {
console.warn(`Caught Validation Error for ${req.path}:`, err.fields);
return res.status(422).json({
message: 'Validation Failed',
details: err?.fields,
});
}
if (err instanceof Error) {
return res.status(500).json({
message: 'Internal Server Error',
});
}
next();
});
I've tried moving around the order of the middlewares and it didn't work. I'm not really sure what else I can do, as moving server.use(session()) to be the most top level middleware was the most suggested fix. Any suggestions?

PassportJS with Express and Axios - req.user is undefined

I am writing a client/server application where the frontend is using React and Axios while the backend is using Express, MySQL and PassportJS. I have a running MySQL database with a users-table, and in the app I can register users successfully with their passwords being hashed and stored in the database. I have also implemented PassportJS to successfully authorize logins. After logging in with a correct username/password combination, a cookie with the following form is saved in the browser:
userId:
s:"qAxPZ8u77YA7_NRSk2sfLxltZI3D5klX.5okMTprFTBBq4RFwyCd2ptkAfv9dfL9Z7IViSK5bGpg"
I don't know if anything seems incorrect about the above cookie. It has some other properties of course like expires etc., but no obvious "user"-object or similar except for the string saved to userId.
Main problem is when I try to check whether a user is logged in to the app on the server side. I use axios on the client side, setup like this:
import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000/api/v1';
axios.defaults.withCredentials = true;
And from the login-module (could be anyone but I used this to test) of my React app I call on a method I have saved which looks like this:
login() {
return axios.get("/login").then((response) => {
console.log(response);
});
}
This sends the request to the backend which is set up like this:
index.ts
import express from 'express';
import router from '../src/router';
import path from 'path';
import db from '../src/mysql-pool';
require('dotenv').config()
const app = express();
const passport = require('passport');
const flash = require('express-flash');
const session = require('express-session');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
app.use(express.static(path.join(__dirname, '/../../client/public')));
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser(process.env.SESSION_SECRET));
app.use(flash());
app.use(session({
key: "userId",
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
expires: 86400000 // ms, aka 24 hours
}
}));
app.use(passport.initialize());
app.use(passport.session());
const initializePassport = require('./passport-config');
initializePassport(
passport,
(username: string) => {
return new Promise<{}>((resolve, reject) => {
db.query('SELECT * FROM users WHERE username = ?', [username], (error, results) => {
if (error) return reject(error);
if (!(results.length > 0)) {
return reject({ message: "User doesn't exist." });
}
resolve(results[0]);
});
});
},
(id: number) => {
return new Promise<{}>((resolve, reject) => {
db.query('SELECT * FROM users WHERE user_id = ?', [id], (error, results) => {
if (error) return reject(error);
if (!(results.length > 0)) {
return reject({ message: "User doesn't exist." });
}
resolve(results[0]);
});
});
}
);
// the method being called from the client side
router.get('/login', (request, response) => {
console.log(request.user);
if (request.user) {
response.send({ loggedIn: true, user: request.user });
} else {
response.send({ loggedIn: false })
}
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash : true
}));
app.use('/api/v1', router);
const port = 3000;
app.listen(port, () => {
console.info(`Server running on port ${port}`);
});
The router is declared in another file called router.ts:
import express from 'express';
import { registerService, loginService } from './services'; // file with some MySQL database queries
require('dotenv').config()
const bcrypt = require('bcrypt');
const saltRounds = 10;
const router = express.Router();
// [.. some unrelated and unproblematic api-calls and routes omitted here ..]
router.post('/register', (request, response) => {
const username = request.body.username;
const password = request.body.password;
if (username && username.length != 0) {
bcrypt.hash(password, saltRounds, (error: Error, hash: string) => {
if (error) response.status(500).send(error);
registerService.register(username, hash)
.then(() => response.status(201).send('New user registered'))
.catch((error) => response.status(500).send(error));
});
} else response.status(400).send("Can't register user: Missing username og password.");
});
export default router;
And passport is configured in a file called passport-config.ts:
// #ts-nocheck
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
function initialize(passport, getUserByUsername, getUserById) {
const authenticateUser = async (username, password, done) => {
const user = await getUserByUsername(username);
if (user == null) {
return done(null, false, { message: 'No user exists that matches the given username.' })
}
try {
if (await bcrypt.compare(password, user.passwd)) {
return done(null, user)
} else {
return done(null, false, { message: 'Wrong username or password.' })
}
} catch (error) {
return done(error)
}
}
passport.use(new LocalStrategy({ usernameField : 'username', passwordField : 'password'}, authenticateUser));
passport.serializeUser((user, done) => done(null, user.user_id));
passport.deserializeUser((id, done) => {
return done(null, getUserById(id));
});
};
module.exports = initialize;
Now: The PassportJS docs and most guides I have tried to follow say that user data after authenticating is stored as req.user. But this route on the backend:
router.get('/login', (request, response) => {
console.log(request.user);
if (request.user) {
response.send({ loggedIn: true, user: request.user });
} else {
response.send({ loggedIn: false })
}
});
returns undefined.
If I instead call:
router.get('/login', (request, response) => {
console.log(request.session); // console log the session instead of req.user
if (request.user) {
response.send({ loggedIn: true, user: request.user });
} else {
response.send({ loggedIn: false })
}
});
It logs:
Session {
cookie: {
path: '/',
_expires: 86400000,
originalMaxAge: 86400000,
httpOnly: true
}
}
So something is definetly happening.
It just doesn't seem like Passport ever saved the user data in the session after authenticating, or if it did, I can't find it.
Any help would be greatly appreciated, I can include more info as well if needed.
EDIT:
For future reference, the solution ended up having something to do with the order of the commands in index.ts. If I remember correctly I think the app.use(passport.xxx)-commands had to be above alot of the other commands. I am afraid I can't recall exactly what order fixed the issue.

Express login session only lasts one page view

In the code below, when I visit / the first time (not logged onto FB) I'm redirected to the /login page, as expected.
Then I login onto facebook and I'm then taken to /, as expected
If I then refresh the page (while on /) I'm taken back the /login page, as if the session is already over.
It looks like for every new page view of / I'm always asked to login every time.
What am I doing wrong ?
(for testing purposes I'm not yet using a real database and have just set up this preliminary user.js one for the sake of the session..)
user.js
import fs from 'fs'
if (!fs.existsSync('./user.json')) {
fs.writeFileSync('./user.json', JSON.stringify(null))
}
export default {
query(facebookId) {
let user = JSON.parse(fs.readFileSync('./user.json', 'utf8'));
if (user && user.facebookId === facebookId) {
return user
}
return null
},
save(user) {
fs.writeFileSync('./user.json', JSON.stringify(user, null, 2))
return user
},
delete() {
fs.writeFileSync('./user.json', JSON.stringify(null, null, 2))
return true
}
}
server.js
import { Strategy as FacebookStrategy } from 'passport-facebook'
import express from 'express'
import passport from 'passport'
import session from 'express-session'
import fetch from 'node-fetch'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import cors from 'cors'
import cookieParser from 'cookie-parser'
import { ensureLoggedIn } from 'connect-ensure-login'
import FB from './fb'
import USER from './user'
import bodyParser from 'body-parser'
const jsonParser = bodyParser.json()
const {
PORT,
INSTAGRAM_USER_ID,
FACEBOOK_APP_ID,
FACEBOOK_APP_SECRET,
FACEBOOK_PAGE_NAME
} = process.env
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const app = express()
app.use(cors({
origin: '*',
credentials: true,
optionSuccessStatus: 200
}))
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', `http://localhost:${PORT}`)
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
res.header('Access-Control-Allow-Methods', 'POST, GET')
next()
})
app.use(cookieParser())
app.use(bodyParser.json({limit: "50mb"}));
app.use(bodyParser.urlencoded({limit: "50mb", extended: true, parameterLimit:50000}))
app.use(session({ secret: 'googoogaga', resave: false, saveUninitialized: false }))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new facebookStrategy({
clientID : FACEBOOK_APP_ID,
clientSecret : FACEBOOK_APP_SECRET,
callbackURL : `http://localhost:${PORT}/facebook/callback`,
profileFields: ['id', 'displayName']
}, function(accessToken, refreshToken, profile, done) {
let user = USER.query(profile.id)
if (user) {
return done(null, user)
} else {
user = USER.save({
facebookId: profile.id,
accessToken
})
return done(null, user);
}
}));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
app.get('/auth/facebook', passport.authenticate('facebook', { scope:'email,instagram_basic,pages_show_list' }));
app.get('/facebook/callback', passport.authenticate('facebook', {
successRedirect : '/',
failureRedirect : '/login'
}));
app.get('/login', (req,res) => {
res.sendFile(__dirname + '/public/login.html');
})
app.get('/', ensureLoggedIn('/login'), (req,res) => {
res.status(200).send({ user: req.user })
})
app.get('/logout', function(req, res){
req.session.destroy(()=>{
USER.delete()
res.redirect('/login')
})
})
app.listen(PORT)
It was because of nodemon.
Every time the user logs in I update some files and I forgot to tell nodemon to ignore those changes so the server restarts every time due to those file changes.
Whenever the server restarts the session is also reset.
Be careful with nodemon, make sure you place any files your server will be changing inside a folder and tell nodemon to ignore it.
On the other hand, a server might restart for other reasons as well. Why should the session be reset every time ? Isn't there a way around it ?.

Passport.js throws "missing credentials" error with local authentication strategy even when custom usernameField is set

I'm trying to implement passport.js's local strategy for authentication. My server is using express routes (I believe this might be the cause of the problem).
If I try to pass anything on the frontend with Axios, the server throws me the error "Missing credentials", even though console logs on the server show me correct data was received.
My main server file:
import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
import passport from 'passport';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import authStrategy from "./utils/passportConfig";
// enables ENV variables to be present under command proccess.env
require('dotenv').config();
// enables express.js on the app and defines the port
const app = express();
const port = process.env.PORT || 5000;
// enables CORS - cross origin resource sharing -
// makes possible requesting resources from another domain
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
const secret = process.env.SECRET;
app.use(session({
secret: secret!,
resave: true,
saveUninitialized: true,
}))
app.use(cookieParser(secret));
app.use(passport.initialize());
app.use(passport.session());
authStrategy(passport);
// mongoose helps us connect to our MongoDB database
const uri = process.env.MONGO_URI!;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true });
const connection = mongoose.connection;
connection.once('open', () => {
console.log("MongoDB databse connection established successfully");
});
// Routes
const usersRouter = require('./routes/users')(passport);
app.use('/user', usersRouter);
// starts the server, and listens for changes on predefined port
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
My passport local strategy configuration:
import User, { IUser } from "../models/user.model";
import bcrypt from "bcrypt";
import * as passportLocal from "passport-local";
import { PassportStatic } from "passport";
const localStrategy = passportLocal.Strategy;
export default module.exports = (passport: PassportStatic) => {
passport.use(
new localStrategy({
usernameField: "email",
},
(email, password, done) => {
User.findOne({ email: email.toLowerCase() }).exec()
.then((user) => {
if (!user) {
return done(null, false, { message: "User with that email does not exist"});
}
bcrypt.compare(password, user.password, (err) => {
if (err) {
return done(null, false, { message: "Incorrect password" });
}
return done(null, user);
})
})
.catch((err) => {
return done(err);
})
})
)
passport.serializeUser((req: any, user: any, done: any) => {
done(null, user.id);
})
passport.deserializeUser((id, done) => {
User.findOne({_id: id}, (err: any, user: any) => {
done(err, user);
});
})
}
My express route handling:
import express from "express";
import { PassportStatic } from "passport";
module.exports = (passport: PassportStatic) => {
const router = express.Router();
router.route('/login').post( function (req, res, next) {
console.log("####", req.body)
passport.authenticate('local', function (err, user, info) {
console.log("MMMM", err, user, info)
if (err) { return next(err); }
if (!user) { return res.status(500).json("User does not exist") }
req.logIn(user, err => {
if (err) {
return next(err);
}
res.status(200).json("Successfully authenticated");
console.log(req.user);
})
})(res, res, next);
});
return router;
}
What console logs on login router return:
#### { email: 'stackoverflow#test.com', password: 'fakepassword' }
MMMM null false { message: 'Missing credentials' }
All solutions to this problem I have found say, that Missing credentials error is due to passport authentication strategy expecting username and password key, and that if you pass anything else, you need to let passport know. As you can see in the passport strategy config file, I have done that.
passport.use(
new localStrategy({
usernameField: "email",
},
(email, password, done) => {
...
What might be the issue here? Is passport not being passed correctly from server.ts? Does the passport not use configured local strategy?
Used packages versions:
express: 4.17.1 |
express-session: 1.17.1 |
passport: 0.4.1 |
passport-local: 1.0.0 |
Edit: Issue solved
There is a problem in the express route handling file, I'm passing `req` twice in the authentication middleware.
I have marked the first reply as correct, as that is the solution most people need when they receive Missing credentials error.
It seems like you have missed the password field while configuring the passport local strategy.
It must look something like this:
passport.use(
"local",
new LocalStrategy(
{
usernameField: "email",
passwordField: "password",
passReqToCallback: false, //optional
},
async (username, password, done) => {
...

node.js - Passport not persisting across browser requests, works with Postman

I am currently using the create-react-app boiler plate and have been attempting to add auth. I am using axios as my promise based HTTP libray with React.js. I have been using node with express, express-session, passport and passport-local on the backend.
Here is my server.js file with some exlusions:
const express = require('express');
const mysql = require('mysql');
const app = express();
const cors = require('cors');
const session = require('express-session');
const passport = require('passport');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const LocalStrategy = require('passport-local').Strategy;
// Express only serves static assets in production
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
}
app.set('port', (process.env.PORT || 3001));
app.use(cors({
credentials: true,
origin: 'http://localhost:3000'
}));
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(session({
secret: 'topsecretpassword',
resave: true,
saveUninitialized: false,
cookie: {
path: '/',
originalMaxAge: 1000 * 60 * 60 * 24,
httpOnly: true,
secure: false
}
}));
app.use(passport.initialize());
app.use(passport.session());
// Setup Database connection
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'mvy_db'
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(user, done) {
connection.query('SELECT * FROM users WHERE id=?', user, function(err, userId) {
if (err) {
res.status(400).json({
error: 'Database Error',
id: userId[0]
});
}
done(err, userId[0]);
});
});
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
},
function(email, password, done) {
connection.query('SELECT * FROM users WHERE email=?', email, function(err, user) {
if (err) {
return done(err);
}
if (!user.length) {
return done(null, false, { message: 'Incorrect email.' });
}
if (user[0].password !== password) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user[0]);
});
}
));
app.post('/signin', passport.authenticate('local'), function(req, res) {
console.log(req.session);
return res.send('login success!');
});
function isAuthenticated (req,res,next){
console.log(req.session);
if(req.session.passport.user)
return next();
else
return res.status(401).json({
error: 'User not authenticated'
})
}
app.get('/checkauth', isAuthenticated, function(req,res) {
res.status(200).json({
status: 'User Authenticated!'
});
})
app.get('/signout', function(req,res) {
req.session.destroy();
res.status(200).json({ success: 'successfully signed out' });
})
Using postman (and even on the browser), I am able to successfully login and the following is held in the req.session object :
cookie:
{ path: '/',
_expires: null,
originalMaxAge: 86400000,
httpOnly: true,
secure: false },
passport: { user: 1 } }
my login request using axios:
return axios.post(ROOT_URL + 'signin', {
email: e.target.email.value,
password: e.target.password.value
}).then((response) => {
if (response.status === 200) {
console.log(response);
}
})
My checkAuth request using axios (this is where I get a 500 error returned):
axios.get(ROOT_URL + 'checkauth', { withCredentials: true })
.then((response) => {
if (response.status === 200) {
return true;
} else {
return false;
}
});
The req.session object after checking authentication before the error message, note that the passport object doesn't exist anymore:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: 86400000,
httpOnly: true,
secure: false } }
This is the error message I get on the console when I attempt to check that the user is authorized:
TypeError: Cannot read property 'user' of undefined
at isAuthenticated (/server.js:94:26)
I've been banging my head for hours, trying to resolve this issue. I thought it might have something to do with CORS, but after hours of playing around with it that doesn't seem to be the case. It's still plausible that it's a CORS issue, but what's really flustering me is that it works full well with Postman but not on my Chrome browser. Any help is appreciated!
Alright, so I found the solution to my problem. It appeared to be an issue with axios and the configuration of my get requests. For some reason, using the structure axios.get(URL) .then(response) doesn't work with the withCredentials property.
Instead, I had to send my request as:
axios(ROOT_URL + 'checkauth', {
method: 'get',
withCredentials: true
})
.then((response) => {
if (response.status === 200) {
return true;
} else {
return false;
}
});
Oh because I forgot that axious doesn’t send credentials by default I had to stick with jwt and completely removed session.
You can define an instance of axious which will allow you to make requests much more simply
const $axios = axios.create({
baseURL: 'https://some-domain.com/api/',
withCredentials: true
});

Resources