Greetings. I've a NodeJS server as:
app.js
'use strict';
const http = require('http');
const express = require('express');
const session = require('express-session');
const pino = require('pino');
const pinoHttp = require('pino-http');
const passport = require('./config/passport');
const httpErrors = require('http-errors');
module.exports = function main(options, cb) {
// Set default options
const ready = cb || function() {};
const opts = Object.assign(
{
// Default options
},
options
);
const logger = pino();
// Server state
let server;
let serverStarted = false;
let serverClosing = false;
// Setup error handling
function unhandledError(err) {
// Log the errors
logger.error(err);
// Only clean up once
if (serverClosing) {
return;
}
serverClosing = true;
// If server has started, close it down
if (serverStarted) {
server.close(function() {
process.exit(1);
});
}
}
process.on('uncaughtException', unhandledError);
process.on('unhandledRejection', unhandledError);
// Create the express app
const app = express();
// Common middleware
app.use(pinoHttp({ logger }));
app.use(session({
resave: false,
secret: 'supersecretamazingpassword',
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
require('./routes')(app, opts);
app.use(function fourOhFourHandler(req, res, next) {
next(httpErrors(404, `Route not found: ${req.url}`));
});
app.use(function fiveHundredHandler(err, req, res, next) {
if (err.status >= 500) {
logger.error(err);
}
res.status(err.status || 500).json({
messages: [
{
code: err.code || 'InternalServerError',
message: err.message
}
]
});
});
server = http.createServer(app);
server.listen(8080);
};
routes.js
'use strict';
const pino = require('pino');
const passport = require('./config/passport');
module.exports = function(app, opts) {
const logger = pino();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', req.header('origin'));
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
if (req.method == 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
logger.info(req)
logger.info(res)
next();
});
app.get('/auth/login', passport.authenticate('saml', {
successRedirect: '/',
failureRedirect: '/auth/failed'
}),
(req, res) => {
logger.info("Requesting: /auth/login");
return res.redirect('http://localhost:8088');
}
);
app.get('/auth/failed', (req, res) => {
logger.info("Requesting: /auth/failed");
return res.status(500).json({
message: 'Un error ha ocurrido'
});
});
app.post('/auth/callback', passport.authenticate('saml'), (req, res) => {
logger.info("Requesting: /auth/callback");
return res.redirect('http://localhost:8088');
});
app.get('/auth/check', (req, res) => {
logger.info("Requesting: /auth/check");
logger.info(req.isAuthenticated())
if (!req.isAuthenticated()) {
return res.status(401).json({
message: 'No autorizado'
});
} else {
return res.status(200).json({ user: req.user });
}
});
app.get('/auth/logout', (req, res) => {
logger.info("Requesting: /auth/logout");
req.logout();
return res.redirect('http://localhost:8088');
});
};
Passport configuration is a SAML SSO:
const passport = require('passport');
const passportSaml = require('passport-saml');
const fs = require('fs');
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// SAML strategy for passport -- Single IPD
const strategy = new passportSaml.Strategy(
{
passReqToCallback: true,
entryPoint: 'the-entrypoint-url',
issuer: 'the-issuer',
callbackUrl: 'the-callback-url',
cert: fs.readFileSync('./secret/the-secret-cer.cer', 'utf-8'),
privateKey: fs.readFileSync('./secret/the-secret-key.key', 'utf-8')
},
(req, profile, done) => done(null, profile)
);
passport.use(strategy);
module.exports = passport;
It's okay. I have tested the request by the browser and can log in, keep the user's email in session, and then log out. But, when I call the server paths in the React interface app, I can't read the sessions. I suppose if I call the login paths with the browser it could read the session by React, but I don't.
axios({
method: 'GET',
url: 'the-server/auth/check',
withCredentials: true
})
.then(response => {
logger.info(response.data, 'SAML');
if (response.data) {
setLoading(false);
}
else {
//AuthLogin();
}
})
.catch(error => {
logger.error(error, 'SAML');
//AuthLogin();
})
I really appreciate your help. Best regards my friends.