here is a proper authorize link that I get when using Node.js express application via localhost:3067/login:
and then after login directs me to https://localhost:3067/welcome. Here is what we're trying to get working. only works fine on https://localhost:3067 but the second you use the IIS reverse proxy to access the website via testing.dupps.com then the authorization route does not work. I've tried the default downloadable Node.js applicaiton code that auth0 provides and created my own custom as well in the 2nd code snippet, but no luck the second I use the reverse proxy.
const dotenv = require('dotenv');
const express = require('express');
const https = require('https');
const logger = require('morgan');
const path = require('path');
const fs = require('fs');
const { auth, requiresAuth } = require('express-openid-connect');
const session = require('express-session'); // Require express-session
dotenv.config();
const app = express();
app.set('trust proxy', 'loopback, linklocal, uniquelocal');
app.set('trust proxy', true);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
// Configure express-session middleware
app.use(session({
secret: 'yourSecretKey',
resave: false,
saveUninitialized: false,
cookie: { secure: true, sameSite: 'none' } // Adjust for cross-domain auth
}));
app.use((req, res, next) => {
console.log('Headers:', req.headers);
next();
});
const config = {
authRequired: false,
auth0Logout: true,
secret: '',
baseURL: process.env.BASE_URL || 'https://testing.dupps.com', // Use env var for production URL
clientID: 'oPqqTSH4b6k3FlZGZqdItV2KBVPVR3w8',
issuerBaseURL: 'https://dev-wg2ioezy8v4cunjl.us.auth0.com',
authorizationParams: {
redirect_uri: 'https://testing.dupps.com/callback'
}
};
const port = process.env.PORT || 3067;
if (!config.baseURL && !process.env.BASE_URL && process.env.PORT && process.env.NODE_ENV !== 'production') {
config.baseURL = `https://testing.dupps.com`; // Change this to the reverse proxy URL
}
app.use(auth(config));
// Middleware to make the `user` object available for all views
app.use(function (req, res, next) {
res.locals.user = req.oidc.user;
res.locals.isAuthenticated = req.oidc.isAuthenticated();
next();
});
// Routes (integrated from router)
app.get('/', function (req, res, next) {
const cookieEnabled = req.headers.cookie ? true : false;
res.render('index', {
title: 'Auth0 Webapp sample Nodejs',
isAuthenticated: req.oidc.isAuthenticated(),
cookieEnabled: cookieEnabled
});
});
app.get('/profile', requiresAuth(), function (req, res, next) {
res.render('profile', {
userProfile: JSON.stringify(req.oidc.user, null, 2),
title: 'Profile page'
});
});
// Route to initiate Auth0 login
app.get('/authorize', (req, res) => {
console.log("Redirecting to Auth0...");
res.redirect(
`${process.env.ISSUER_BASE_URL}/authorize?client_id=${process.env.CLIENT_ID}&scope=openid%20profile%20email&response_type=id_token&redirect_uri=${encodeURIComponent(process.env.BASE_URL + '/callback')}&response_mode=form_post&nonce=${req.query.nonce}&state=${req.query.state}`
);
});
// Route to handle Auth0 callback
app.post('/callback', express.urlencoded({ extended: false }), (req, res) => {
console.log("Received callback from Auth0:", req.body);
const { id_token } = req.body;
if (!id_token) {
return res.status(400).send('Authentication failed');
}
// Store user session
req.session.user = id_token;
// Redirect to home or dashboard
res.redirect('/');
});
// Catch 404 and forward to error handler
app.use(function (req, res, next) {
const err = new Error('Not Found');
err.status = 404;
next(err);
});
// Error handlers
app.use((err, req, res, next) => {
console.error('Error:', err);
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: process.env.NODE_ENV !== 'production' ? err : {}
});
});
// Path to your PFX file and passphrase if needed
const pfxPath = path.join(__dirname, 'key.pfx'); // Adjust the path accordingly
const passphrase = ''; // Change this to your actual passphrase
// Create HTTPS options with PFX certificate
const httpsOptions = {
pfx: fs.readFileSync(pfxPath),
passphrase: passphrase // If there's no passphrase, you can omit this
};
// Start the HTTPS server
https.createServer(httpsOptions, app)
.listen(port, () => {
console.log(`Listening securely on ${config.baseURL}`);
});
and here is the custom Node.js app I made:
const dotenv = require('dotenv');
const express = require('express');
const https = require('https');
const path = require('path');
const fs = require('fs');
const session = require('express-session');
const { auth } = require('express-openid-connect');
// Load environment variables
dotenv.config();
const app = express();
// Set up view engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
// Session configuration
app.use(session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
}));
// SSL certificate options
// Note: For production, you should use proper SSL certificates
// For development, you can generate self-signed certificates
const pfxPath = path.join(__dirname, 'key.pfx'); // Adjust the path accordingly
const passphrase = '1234'; // Change this to your actual passphrase
// Create HTTPS options with PFX certificate
const httpsOptions = {
pfx: fs.readFileSync(pfxPath),
passphrase: passphrase // If there's no passphrase, you can omit this
};
// Auth0 configuration
const config = {
authRequired: false,
auth0Logout: true,
baseURL: `https://localhost:${process.env.PORT}`,
clientID: process.env.CLIENT_ID,
issuerBaseURL: process.env.ISSUER_BASE_URL,
secret: process.env.SECRET,
clientSecret: process.env.SECRET, // Added client secret
authorizationParams: {
response_type: 'code',
scope: 'openid profile email'
},
routes: {
login: '/login',
callback: '/callback',
postLogoutRedirect: '/'
},
session: {
rollingDuration: 60 * 60 * 24, // 24 hours in seconds
absoluteDuration: 60 * 60 * 24 * 7, // 7 days in seconds
cookie: {
sameSite: 'Lax'
}
}
};
// Auth router
app.use(auth(config));
// Make user info available to all views
app.use((req, res, next) => {
res.locals.user = req.oidc.user;
res.locals.isAuthenticated = req.oidc.isAuthenticated();
next();
});
// Routes
app.get('/', (req, res) => {
if (req.oidc.isAuthenticated()) {
return res.redirect('/welcome');
}
res.render('index', { title: 'Home' });
});
app.get('/welcome', (req, res) => {
if (!req.oidc.isAuthenticated()) {
return res.redirect('/login');
}
const user = req.oidc.user;
res.render('welcome', {
title: 'Welcome',
user: user
});
});
// Create HTTPS server
const server = https.createServer(httpsOptions, app);
// Start server
const PORT = process.env.PORT || 3067;
server.listen(PORT, () => {
console.log(`Server running on https://localhost:${PORT}`);
});