I tried to implement twitter strategy using PassportJS for my ExpressJS application. However, it always stuck when calling the callback URL. Twitter actually called the callback route (I tried replacing passport.authenticate() with res.json()) but somehow when I put passport.authenticate() it got stuck. What could be the problem?
server
const express = require("express");
const cors = require("cors");
const session = require("express-session");
const csrf = require("csurf");
const compression = require("compression");
const helmet = require("helmet");
const MongoStore = require("connect-mongo");
const router = require("./routes/api.routes");
const passport = require("./middlewares/passport.middleware");
const app = express();
app.use(
cors({
origin: [
"https://api.twitter.com",
],
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
session({
secret: process.env.SECRET,
resave: true,
rolling: true,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: process.env.MONGODB_URI,
}),
cookie: {
// 1 hour
maxAge: 1000 * 60 * 60 * 1,
httpOnly: true,
},
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(csrf());
app.use(helmet());
app.use(compression());
app.use(router);
// error handler
app.use(function (err, req, res, next) {
if (err.code === "EBADCSRFTOKEN") {
// handle CSRF token errors here
return res.status(403).send({ message: "form tampered with" });
}
res.status(err.status || 500);
});
module.exports = app;
routes
// OAuth 1
router.route("/auth/twitter").get(passport.authenticate("twitter"));
router
.route("/auth/twitter/callback")
.get(passport.authenticate("twitter", { failureRedirect: "/error" }), (req, res) => {
// it never reached here
res.status(200).send({ msg: "success!" });
});
router.route("/error").get((req, res) => {
res.status(403).send({ msg: "authentication failed" });
});
passport config
passport.use(
new TwitterStrategy(
{
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:5000/auth/twitter/callback",
passReqToCallback: true
},
async function (token, tokenSecret, profile, cb) {
try {
const user = await users.upsertUser(profile.id);
return cb(null, user);
} catch (err) {
return cb(err);
}
}
)
);
passport.serializeUser((user, cb) => {
cb(null, user.email);
});
passport.deserializeUser(async (username, cb) => {
try {
const user = await users.findUserBy("email", username);
// filter out data
cb(null, user);
} catch (err) {
cb(err);
}
});
Related
Passport is being used to log in via Discord in order to access a Dashboard. Main problem is the logout though, worked before passport v.0.6.0, but now it doesn't. req.logout(); now needs a callback function (see here) to work, but when I now access /logout
on the website I get Error: Login sessions require session support. Did you forget to use 'express-session' middleware?
settings.json
{
"website": {
"support": "https://discord.gg/xxxxxxx",
"domain": "http://localhost:5991"
},
"config": {
"port": 5991,
"callback": "http://localhost:5991/callback",
"clientID": "botId",
"secret": "OAuth2 Secret"
}
}
index.js
const express = require('express');
const url = require('url');
const path = require('path');
const ejs = require('ejs');
const passport = require('passport');
const bodyParser = require('body-parser');
const Strategy = require('passport-discord').Strategy;
const settings = require('./settings.json');
const logger = require('silly-logger');
const favicon = require('serve-favicon');
module.exports = client => {
// website config backend
const app = express();
const session = require('express-session');
const MemoryStore = require("memorystore")(session);
// middleware
app.use(session({
secret: `superdupersecret`,
store: new MemoryStore({ checkPeriod: 86400000 }),
resave: false,
saveUninitialized: false,
}));
app.use(favicon(path.join(__dirname, 'public/assets', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.use(express.json());
app.use(express.urlencoded({
extended: true,
}));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "./views"));
// loading public
app.use('/public', express.static(__dirname + '/public'));
app.use(passport.initialize());
app.use(passport.session());
// initialize discord login
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((obj, done) => done(null, obj));
passport.use(new Strategy({
clientID: settings.config.clientID,
clientSecret: settings.config.secret,
callbackURL: settings.config.callback,
scope: ["identify", "guilds", "guilds.join"],
},
(accessToken, refreshToken, profile, done) => {
process.nextTick(()=>done(null, profile));
},
));
app.get("/login", (req, res, next) => {
if (req.session.backURL) {
// eslint-disable-next-line no-self-assign
req.session.backURL = req.session.backURL;
} else if (req.headers.referer) {
const parsed = url.parse(req.headers.referer);
if (parsed.hostname == app.locals.domain) {
req.session.backURL = parsed.path;
}
} else {
req.session.backURL = "/";
}
next();
}, passport.authenticate("discord", { prompt: null }));
app.get("/callback", passport.authenticate("discord", { failureRedirect: "/" }), async (req, res) => {
res.redirect("/dashboard");
});
app.get("/logout", (req, res, next) => {
req.session.destroy(() => {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
});
const http = require('http').createServer(app);
http.listen(settings.config.port, () => {
logger.success(`Website is online on port ${settings.config.port}, ${settings.website.domain}`);
});
};
EDIT:
I found two ways that end the session:
app.get("/logout", (req, res, next) => {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
app.get("/logout", (req, res, next) => {
req.session.destroy((err) => {
if (err) { return next(err); }
res.redirect("/");
});
});
I've started to convert express project to nestjs. How should it work in Nestjs. Here is working code from Express.
(Code below just redirects to steam sign-in page)
/* eslint-disable space-before-function-paren */
// Require all the installs
var express = require('express');
var passport = require('passport');
var session = require('express-session');
var passportSteam = require('passport-steam');
var SteamStrategy = passportSteam.Strategy;
var app = express();
// Let's set a port
var port = 4000;
// Spin up the server
app.listen(port, () => {
console.log('Listening, port ' + port);
});
// Set up the SteamStrategy
// Required to get data from user for sessions
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// Initiate Strategy
passport.use(
new SteamStrategy(
{
returnURL: 'http://localhost:' + port + '/api/auth/steam/return',
realm: 'http://localhost:' + port + '/',
apiKey: 'My API key',
},
function (identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
)
);
app.use(
session({
secret: 'Whatever_You_Want',
saveUninitialized: true,
resave: false,
cookie: {
maxAge: 3600000,
},
})
);
app.use(passport.initialize());
app.use(passport.session());
// Routes
app.get('/', (req, res) => {
res.send(req.user);
});
app.get(
'/api/auth/steam',
passport.authenticate('steam', { failureRedirect: '/' }),
function (req, res) {
res.redirect('/');
}
);
app.get(
'/api/auth/steam/return',
passport.authenticate('steam', { failureRedirect: '/' }),
function (req, res) {
res.redirect('/');
}
);
The question is how to implement same in the nestjs???
Or if I want to implement middlewares for passport lib (serializeUser, deserializeUser), how should it happen, in nest official docs I found this examples of custom middlewares
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
But how I should use passport middlware
I have been browsing the forum but I am unable to find the error in my code , it always results in false and I am not able to solve it , Please help me...
Is there any other way to authenticate user instead of passport so that I can use it.I am adding more sentences as it is not allowing me to post my query,Sorry..
const http = require("http"),
hostname = "127.0.0.1",
port = 3000,
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
express = require("express"),
passport = require("passport"),
localStrategy = require("passport-local"),
passportLocalMongoose = require("passport-local-mongoose"),
User = require("./models/user");
app = express();
mongoose.connect("mongodb://localhost/drive", { useNewUrlParser: true });
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(passport.initialize());
app.use(passport.session());
app.use(
require("express-session")({
secret: "Beta tumse na ho payega",
resave: false,
saveUninitialized: false
})
);
passport.use(new localStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(bodyParser.urlencoded({ extended: true }));
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
});
app.get("/", function(req, res) {
res.render("index");
});
app.get("/register", function(req, res) {
res.send("hello");
});
app.get("/login", function(req, res) {
res.render("login");
});
app.post(
"/login",
passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login"
}),
function(req, res) {}
);
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
console.log("Not logged");
res.redirect("/login");
}
}
app.get("/secret", isLoggedIn, function(req, res) {
res.send("You are logged in");
});
app.post("/register", function(req, res) {
if (req.body.password === req.body.cpassword) {
User.register(
new User({ username: req.body.username }),
req.body.password,
function(err, user) {
if (err) console.log(err);
else
passport.authenticate("local")(req, res, function() {
res.send("signed up");
});
}
);
} else res.send("Password Mismatch");
});
//DRIVE SCHEMA
//var driveSchema = mongoose.Schema({
// title: String,
// created: { type: Date, default: Date.now }
//});
app.listen(port, hostname, function() {
console.log("Server is running at " + hostname + "/" + port);
});
//./models/user.js file
const mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
I have used passport and jwt library, to authenticate and maintain session for the user. There is no need to maintain user session on server side.
apis/apis.js : This file has all apis end points. /login url will authenticate user using passport and send a token to the client using jwt
const passport = require('passport')
const expRoute = require('express').Router();
let exporter = process.exporter;
expRoute.post('/login', (req, res, next) => {
passport.authenticate(
'local',
{
// successRedirect: '/',
// failureRedirect: '/login',
successFlash: 'Welcome!',
failureFlash: 'Invalid username or password.'
},
(err, user, info) => {
if (err) {
return res.status(500).json(err)
}
else if (user) {
return res.status(200).json({
token: exporter.generateToken(user)
})
}
else {
return res.status(400).json(info)
}
}
)(req, res, next);
})
expRoute.get('/view', exporter.authenticateToken, (req, res) => {
let param = req.finalTokenExtractedData
if (param && exporter.isObjectValid(param, 'tokenId', true, true)) {
let condition = {
_id: param.tokenId
}
let options = {
_id: 0,
password: 0,
__v: 0
}
process.USER.findOne(condition, options) // mongo find
.then((data) => {
res.status(200).json({
result: data,
msg: 'success'
})
})
.catch((mongoErr) => {
exporter.logNow(`USER mongo Error: ${mongoErr}`)
res.status(400).json({
msg: 'user not found'
})
})
}
else {
res.status(404).json({
msg: 'invalid token'
})
}
})
module.exports = expRoute
common/env.js: This file will initialise all connections such mongo, require few files will be used as global
process.CONFIG = require('../configs/config.json')
process.exporter = require("../lib/exporter.js")
process.dbInit = (globalName, mongoUrl, collectionName) => {
require("../models/db-init.js")(mongoUrl, collectionName)
.then((modelObj) => {
process[globalName] = modelObj // will be used as global
})
.catch((dbInitErr) => {
process.exporter.logNow(`dbInit Error: ${dbInitErr}`)
process.exit()
});
}
lib/exporter.js: This file has exporter class which consist of all major functions like mongo connection, authenticateToken, verifyPassword, etc.
const fs = require('fs'),
redis = require("redis"),
path = require("path"),
mongoose = require('mongoose'); mongoose.set('useCreateIndex', true);
const Schema = mongoose.Schema;
var bcrypt = require('bcryptjs')
var jwt = require('jsonwebtoken')
class Exporter {
mongoConnection(mongoURI, schemaObj) {
return new Promise(async (resolve, reject) => {
if (!mongoURI || typeof mongoURI == 'undefined' || mongoURI.length < 1)
return reject('invalid mongo connection url');
return resolve(mongoose.createConnection(mongoURI, { useNewUrlParser: true }))
})
}
createMongoSchema(schemaObj) {
return (new Schema(schemaObj));
}
createMongoModel(mongoDB, collectionName, newSchema) {
if (newSchema)
return mongoDB.model(collectionName, newSchema)
return mongoDB.model(collectionName)
}
authenticateToken(req, res, next) {
const bearerHeader = req.header('authorization')
if (typeof bearerHeader != 'undefined') {
const bearer = bearerHeader.split(' ')
const bearerToken = bearer[1]
jwt.verify(bearerToken, process.CONFIG.jwt.token.activated, (err, data) => {
if (err)
res.status(400).json({
msg: "Invalid token or please try to login again"
})
else {
process.exporter.getSingleHashKeysValuesFromRedis('expired_token', bearerToken)
.then((redisTokendata) => {
if (redisTokendata)
res.status(400).json({
msg: "token expired"
})
else {
req.finalTokenExtractedData = data
// if (req.originalUrl.trim() == process.logoutURL.trim())
req.jwtToken = {
token: bearerToken,
secret: process.CONFIG.jwt.token.activated
}
next()
}
})
.catch((redisTokenError) => {
process.exporter.logNow(`redis token error: ${redisTokenError}`)
res.status(400).json({
msg: "Some went wrong while checking token. Please try later."
})
})
}
})
}
else
res.status(400).json({
msg: "invalid token"
})
}
generateToken(data) {
let expiry = new Date();
// expiry.setDate(expiry.getDate() + 7)
expiry.setMinutes(expiry.getMinutes() + 5)
return jwt.sign({
tokenId: data._id,
exp: parseInt(expiry.getTime() / 1000),
}, process.CONFIG.jwt.token.activated)
}
createPassword(password) {
return new Promise((resolve, reject) => {
if (typeof password == 'undefined' && password == '')
return reject('password empty')
bcrypt.hash(password, 10, async (bErr, hash) => {
if (bErr)
reject(bErr)
else
resolve(hash)
})
})
}
verifyPassword(enteredPassword, savePassword) {
return bcrypt.compareSync(enteredPassword, savePassword)
}
}
module.exports = (new Exporter());
index.js: This is file which you will execute node index.js.
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const passport = require('passport');
require('./common/env')
require('./configs/passport')
const app = express()
const cors = require('cors')
app.use(cors());
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true}))
app.use(passport.initialize())
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 apis = require('./apis/api')
app.use('/user', apis)
/**
* 404 Handler
*/
app.use((req, res, next)=>{
return res.status(404).send("Endpoint "+req.url +" not found");
})
/**
* if any error or exception occurred then write into a JS file so that app can be restarted
*/
process.on('uncaughtException', (err) => {
console.error(err.stack);
});
app.listen(3000, function(server) {
console.log("App listening at 3000");
});
When index.js file has been executed successfully and listening to a port 3000, then use this URL http://localhost:3000/user/login for authentication, it will accept your username and password, then authenticate using passport and send a token to the client as response. The token can contain user data in encrypted form and have expiry time.
Reference link: https://github.com/arjun-707/login-logout-jwt-nodejs
You need the express-session module.
server.js
// Require a possible config.js file with your configuration variables
const Config = require('./models/config.js');
// If the config module is formed as a class
const config = new Config();
const express = new('express');
const app = express();
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const uuid = require('uuid/v4');
const mongoose = require('mongoose');
// Require your custom passport local strategy file
const passport = require('./models/sessions');
mongoose.connect('mongodb://localhost:27017/your_db_name', {
useNewUrlParser: true
});
// Set the session options
app.use(session({
// Use UUIDs for session IDs
genid: (req) => {
return uuid()
},
// If you want to store the session in MongoDB using mongoose
// Require your personal mon
store: new MongoStore({
mongooseConnection: mongoose.connection
}),
// Define the session secret in env variable or in config file
secret: process.env.SESSION_SECRET || config.sessionSecretKey,
resave: false,
saveUninitialized: true
}));
// Initialize the passport module
app.use(passport.initialize());
// Tell to passport to use session
app.use(passport.session());
./models/session.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt-nodejs');
// Your custom MongoDB connection module
const db = require('./db');
// Configure passport.js to use the local strategy
passport.use(new LocalStrategy({
usernameField: 'username'
},
(username, password, done) => {
db.User.find({
username: username // But it could use email as well
}).then(res => {
const user = JSON.parse(JSON.stringify(res[0]));
if (!user) {
return done(null, false, {
message: 'Invalid credentials.\n'
});
}
if (!bcrypt.compareSync(password, user.password)) {
return done(null, false, {
message: 'Invalid credentials.\n'
});
}
return done(null, user);
}).catch(error => done(error));
}
));
// Tell passport how to serialize the user
passport.serializeUser((user, done) => {
done(null, user._id);
});
// Tell passport how to deserialize the user
passport.deserializeUser((id, done) => {
db.User.find({
_id: id
}).then(res => {
const response = typeof res !== undefined && res.length != 0 ? JSON.parse(JSON.stringify(res[0])) : null;
done(null, response)
}).catch(error => done(error, false))
});
// Export passport for external usage
module.exports = passport;
./models/db.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const uuid = require('uuid/v4');
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/your_db_name', {
useNewUrlParser: true
});
// Define the models container
let models = {};
// Prepare your user schema
const userSchema = Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
// Assign the user schema
models.User = mongoose.model('User', userSchema);
// Export for external usage
module.exports = models;
/*
In that way you can wrap in "models" all schemas:
const newSchema = Schema({
name: String
});
models.Newschema = mongoose.model('Newschema', newSchema);
module.exports = models;
And use it externally like:
const db = require('./models/db');
db.User.find({}).then(docs => {}).catch(err => {});
db.Newschema.find({}).then(docs => {}).catch(err => {});
Etc....
*/
./models/config.js
class Config {
constructor() {
this.sessionSecretKey = "my-awesome-secretkey";
/* And other configurations */
}
}
module.exports = Config;
/*
Externally use like:
const Config = require('./models/config');
const config = new Config();
let sessionSecretKey = config.sessionSecretKey;
*/
Then you can use the req.isAuthenticated() after the login:
// POST the username and password to '/login' router
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (info) {
return res.send(info.message)
}
if (err) {
return next(err);
}
if (!user) {
return res.sendStatus(404); // Is a shortcut
// OR -> res.status(404).end();
// OR -> res.status(404).send('Not found'); as you like
}
req.login(user, (err) => {
if (err) return next(err);
// Store the user object retrieved from MongoDB in `req.session`
req.session.user = user;
return res.sendStatus(200); // Is a shortcut
// OR -> res.status(200).end();
// OR -> res.status(200).send('OK'); as you like
})
})(req, res, next);
});
// The logout logic
app.get('/logout', verifySession, function (req, res) {
req.session.destroy(function (err) {
req.logout();
res.redirect('/');
});
});
// Verify the session to protect private routers
function verifySession(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
// Forbidden
res.redirect('/');
// OR -> res.sendStatus(403);
// OR -> res.status(403).end();
// OR -> res.status(403).send('Forbidden'); as you like
}
}
Of course you have to run npm install with all the dependencies required defined in package.json file or manually instal with npm i express-session#latest --s for all the dependencies required: npm i module-name#latest --s.
Don't forget the
const server = app.listen(config.port || 3000, () => {
console.log(`Server running on ${server.address().port} port.`);
});
At the end of server.js file. I hope that it will be useful for you.
I am working on user login page with node.js, passport, and postgres. I thought I got user authentication working. However, when I try to change pages I get this error and my server won't load anything. {"message":"log is not defined","error":{}}. I have been stuck on this error for hours now and can't figure out what is causing it. I am guessing that the session is somehow getting messed up but I could be wrong. I am hoping someone knows the answer. Here is my relevant code.
I am extremely new to web development and because of that I am sure it is probably something simple I am missing.
main-config.js
(function(appConfig) {
'use strict';
// *** main dependencies *** //
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');
const flash = require('connect-flash');
const morgan = require('morgan');
const nunjucks = require('nunjucks');
const passport = require('passport');
// *** view folders *** //
const viewFolders = [
path.join(__dirname, '..', 'views')
];
// *** load environment variables *** //
require('dotenv').config();
appConfig.init = function(app, express) {
// *** view engine *** //
nunjucks.configure(viewFolders, {
express: app,
autoescape: true
});
app.set('view engine', 'html');
// *** app middleware *** //
if (process.env.NODE_ENV !== 'test') {
app.use(morgan('dev'));
}
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret: 'anything',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(path.join(__dirname, '..', '..', 'client')));
};
})(module.exports);
local.js
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
(username, password, done) => {
return db.one("SELECT * " +
"FROM Users " +
"WHERE Email=$1", [username])
.then((result)=> {
return done(null, result);
})
.catch((err) => {
return done(null, false, {message:'Wrong user name or password'});
});
}));
passport.js
module.exports = () => {
passport.serializeUser((user, done) => {
done(null, user.userid);
});
passport.deserializeUser((id, done)=>{
log.debug("deserialize ", id);
db.one("SELECT * FROM User " +
"WHERE user_id = $1", id)
.then((user)=>{
done(null, user);
})
.catch((err)=>{
done(new Error(`User with the id ${id} does not exist`));
})
});
};
auth.js
router.post('/login', authHelpers.loginRedirect, (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) { handleResponse(res, 500, 'error'); }
if (!user) {
console.log("User Not Found");
handleResponse(res, 404, 'User not found');
}
if (user) {
req.logIn(user, function (err) {
if (err) { handleResponse(res, 500, 'error'); }
handleResponse(res, 200, 'success');
});
}
})(req, res, next);
});
It's a clear error message - log is not defined in the following line in passport
log.debug("deserialize ", id);
Define your log object with a logger and everything should be good. Or just remove it for now.
For some reason req.user is undefined, and after 4+ hours of trying to figure out why, I'm asking here. I even copy-pasted the server/index.js file of a friend's server, changed the auth strategy so it worked for mine, and I get the same issue.
Everything else is working. It redirects to auth0, comes back to the correct place, either creates a new user in the DB or finds the user. In passport.serializeUser it has all the data I passed along. But when I hit the '/auth/me' endpoint, req.user is undefined.
server/index.js
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const session = require("express-session");
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');
const massive = require('massive');
const axios = require('axios');
const process = require("process");
const moment = require('moment');
const app = express();
//app.use(express.static(__dirname + './../build'));
app.use(bodyParser.json());
app.use(cors());
app.use(session({
secret: process.env.SECRET,
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
// Use the session middleware
massive(process.env.CONNECTION_STRING)
.then( (db) => {
console.log('Connected to Heroku')
app.set('db', db);
}).catch(err=>console.log(err))
passport.use(new Auth0Strategy({
domain: process.env.AUTH_DOMAIN,
clientID: process.env.AUTH_CLIENT_ID,
clientSecret: process.env.AUTH_CLIENT_SECRET,
callbackURL: process.env.AUTH_CALLBACK
}, (accessToken, refreshToken, extraParams, profile, done) => {
const db = app.get("db");
const userData = profile._json;
db.find_user([userData.identities[0].user_id]).then(user => {
if (user[0]) {
return done(null, user[0]);
} else {
db.create_user([
userData.given_name,
userData.family_name,
userData.email,
userData.identities[0].user_id
])
.then(user => {
return done(null, user);
});
}
});
}))
passport.serializeUser( (user, done) => {
//console.log('serializeuser', user)
done(null, user);
})
passport.deserializeUser( (id, done) => {
app.get("db").find_session_user([id])
.then(user => {
console.log(user);
done(null, user[0]);
});
})
app.get('/auth', passport.authenticate('auth0'));
app.get('/auth/callback', passport.authenticate('auth0', {
successRedirect: process.env.SUCCESS_REDIRECT
}))
app.get('/auth/me', (req, res) => {
console.log('auth/me endpoint hit')
console.log(req.user)
if(!req.user){
return res.status(401).send('No user logged in.');
}
return res.status(200).send(req.user);
})
app.listen(process.env.PORT, () => console.log(`Listening on port: ${process.env.PORT}`));
server/.env
CONNECTION_STRING=postgres:*****
SECRET=*******
AUTH_DOMAIN=****.auth0.com
AUTH_CLIENT_ID=***
AUTH_CLIENT_SECRET=***
AUTH_CALLBACK=http://localhost:8084/auth/callback
SUCCESS_REDIRECT=http://localhost:3000/
PORT=8084
Try moving the app.get('/auth', passport.authenticate('auth0')); line after the app.get('/auth/me', (req, res) => { block. app.get can do regex matches and goes with the first one that matches (http://expressjs.com/en/api.html#path-examples), and I think it's trying to run the /auth logic for the /auth/me path.