Я пытаюсь создать функцию единого входа, которая проверяет, был ли пользователь уже подготовлен, и либо создает пользователя, либо обновляет базу данных самой последней информацией.
Я установил обновление / вставку, но теперь не могу вернуть идентификатор пользователя (uid или UserID) из запроса.
Я оставил несколько замечаний, которые я пытался прокомментировать в разделе.
По сути, запрос, который выполняет вставку / обновление, вложен в другой, который находится внутри post_assert. Мне нужно значение iresults.insertId для только что подготовленных пользователей и результат результатов [0] .nid из запроса первого уровня, который будет сохранен в массиве cookieData.
Сейчас я получаю остальные файлы cookie (firstName, lastName, username, email, wwwid, country и geo, но из-за моей жизни не могу получить свойство cookieData.userid, которое будет добавлено до него отправляется обратно в браузер.
Это API-интерфейс expressJS REST, который отправляет данные обратно в приложение VueJS.
Я пробовал обратные вызовы, а также глобальные переменные, но, похоже, ничто не добавляет новое значение в массив.
sp.post_assert(idp, options, function (err, saml_response) {
if (err)
res.redirect('https://www.example.com/');
var sessionID = saml_response.response_header.id;
setCookie(res, req, sessionID);
var refererLocation = req.cookies.referLocation;
// Set User Data Variables
const firstName = saml_response.user.attributes.givenName;
const middleName = null;
const lastName = saml_response.user.attributes.sn;
const username = saml_response.user.attributes.uid;
const email = saml_response.user.attributes.mail;
const wwid = saml_response.user.attributes.employeeID;
const country = saml_response.user.attributes.country;
const geo = saml_response.user.attributes.geographicRegion;
/*function setCookieData(val) {
cookieData.userid = val;
}*/
// let userid;
// Check if user exists in DB
res.locals.connection.query('SELECT * FROM users WHERE username = ?', [username], function (error, results, fields) {
if (error) throw error;
// Get the Current Date-Time for insertion
const accessDateTime = new Date();
const adtYear = accessDateTime.getFullYear();
const adtMonth = accessDateTime.getMonth() + 1;
const adtDay = accessDateTime.getDate();
const adtHour = accessDateTime.getHours();
const adtMin = accessDateTime.getMinutes();
const adtSec = accessDateTime.getSeconds();
const dts = `${adtYear}-${adtMonth}-${adtDay} ${adtHour}:${adtMin}:${adtSec}`;
// let userid;
// If results is empty, then the user who just logged in does not currently have
// an account provisioned, so set them up an account.
if (!(results.hasOwnProperty(0))) {
res.locals.connection.query('INSERT INTO users SET ?', {first_name: firstName, middle_name: middleName, last_name: lastName, username: username, email: email, status: 1, created: dts, access: dts, login: dts}, function (ierror, iresults, ifields){
if (ierror) throw ierror;
// Set the User Data Cookie
// res.locals.userid = iresults.insertId;
// setUserIdValue(iresults[0].insertId);
// res.clearCookie('UserInfo');
// res.cookie('UserInfo', cookieData);
// cookieData.userid=iresults[0].insertId;
// res.cookie('UserInfo', cookieData);
app.locals.userid = iresults[0].insertId;
});
// Else, the result was NOT empty, then the user already exists in the DB,
// so just update their Access and Login DATETIME fields.
} else {
res.locals.connection.query('UPDATE users SET login = ?, access = ? WHERE uid = ?', [dts, dts, results[0].uid], function (ierror, iresults, ifields){
if (ierror) throw ierror;
// userid = results[0].uid;
// Set the User Data Cookie
// res.locals.userid = results[0].uid;
// setUserIdValue(results[0].uid);
// res.clearCookie('UserInfo');
// res.cookie('UserInfo', cookieData);
// cookieData.userid=results[0].uid;
// res.cookie('UserInfo', cookieData);
app.locals.userid = results[0].uid;
});
}
});
const cookieData = {
firstName: firstName,
lastName: lastName,
username: username,
email: email,
wwid: wwid,
country: country,
geo: geo,
userid: app.locals.userid,
};
res.cookie('UserInfo', cookieData);
//Add saml ID to database with expiration date
if (refererLocation != undefined) {
res.clearCookie("referLocation");
res.redirect('https://www.example.com' + refererLocation);
} else {
res.redirect('https://www.example.com/uri');
}
// Save name_id and session_index for logout
// Note: In practice these should be saved in the user session, not globally.
// name_id = saml_response.user.givenName + "," + saml_response.sn;
// session_index = saml_response.user.session_index;
//var first = saml_response.user.attributes.givenName;
//var last = saml_response.user.attributes.sn;
//res.send("Hello, " + first + " " + last);
});
РЕДАКТИРОВАТЬ (9-11-2018)
Я разбил его на наиболее простую концепцию и до сих пор не могу заставить его вернуть значение 'userid' в cookie. Даже после установки всего на ASYNC и AWAIT.
app.post('/api/v1/saml/acs', function (req, res) {
const options = {
request_body: req.body,
allow_unencrypted_assertion: true
};
sp.post_assert(idp, options, async function (err, saml_response) {
if (err)
res.redirect('https://www.example.com/');
const sessionID = saml_response.response_header.id;
const user = saml_response.user.attributes;
// Set User Data Variables
const firstName = user.givenName;
const middleName = null;
const lastName = user.sn;
const username = user.uid;
const email = user.mail;
const wwid = user.employeeID;
const country = user.country;
const geo = user.geographicRegion;
app.locals.UserData = {
firstName: firstName,
lastName: lastName,
username: username,
email: email,
wwid: wwid,
country: country,
geo: geo,
// userid: '',
};
// Check if user exists in DB
await res.locals.connection.query('SELECT * FROM users WHERE username = ?', [app.locals.UserData.username], async function (error, results, fields) {
if (error) throw error;
// Get the Current Date-Time for insertion
const accessDateTime = new Date();
const adtYear = accessDateTime.getFullYear();
const adtMonth = accessDateTime.getMonth() + 1;
const adtDay = accessDateTime.getDate();
const adtHour = accessDateTime.getHours();
const adtMin = accessDateTime.getMinutes();
const adtSec = accessDateTime.getSeconds();
const dts = `${adtYear}-${adtMonth}-${adtDay} ${adtHour}:${adtMin}:${adtSec}`;
// If results is empty, then the user who just logged in does not currently have
// an account provisioned, so set them up an account.
if (!(results.hasOwnProperty(0))) {
await res.locals.connection.query('INSERT INTO users SET ?', {first_name: app.locals.UserData.firstName, middle_name: app.locals.UserData.middleName, last_name: app.locals.UserData.lastName, username: app.locals.UserData.username, email: app.locals.UserData.email, status: 1, created: dts, access: dts, login: dts}, async function (ierror, iresults, ifields){
if (ierror) throw ierror;
app.locals.UserData.userid = 22;
// app.locals.UserData.userid = iresults.insertID;
});
} else {
await res.locals.connection.query('UPDATE users SET login = ?, access = ? WHERE uid = ?', [dts, dts, results[0].uid], async function (ierror, iresults, ifields){
if (ierror) throw ierror;
app.locals.UserData.userid = 44;
// app.locals.UserData.userid = results[0].uid;
});
}
});
// Set User Session Cookie
res.cookie('UserData', app.locals.UserData);
// Set SAML Session Cookie
setCookie(res, req, sessionID);
// Get the referrer location
var refererLocation = req.cookies.referLocation;
// If it is undefined, then send the user back to where they started the Sign On process.
if (refererLocation != undefined) {
res.clearCookie("referLocation");
res.redirect('https://www.example.com' + refererLocation);
} else {
res.redirect('https://www.example.com/uri');
}
});
});
Ответ на dmfay
Я полагаю, что следовал вашему совету, но он по-прежнему не возвращает свойство 'userid'.
Я добавил параметр 'next' в
app.post('/api/va/saml/acs', function (){...});
и добавил вызов 'next ()' в конце
sp.post_assert(idp, options, async function(...){
// logic here with nested calls trying to update app.locals.UserData
next();
});
Я также пробовал вызов 'next ()' вне post_assert, и я получаю это сообщение:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
См. Ниже обновленный код.
app.post('/api/v1/saml/acs', function (req, res, next) {
const options = {
request_body: req.body,
allow_unencrypted_assertion: true
};
sp.post_assert(idp, options, async function (err, saml_response) {
if (err)
res.redirect('https://www.example.com/');
const sessionID = saml_response.response_header.id;
const user = saml_response.user.attributes;
// Set User Data Variables
const firstName = user.givenName;
const middleName = null;
const lastName = user.sn;
const username = user.uid;
const email = user.mail;
const wwid = user.employeeID;
const country = user.country;
const geo = user.geographicRegion;
app.locals.UserData = {
firstName: firstName,
lastName: lastName,
username: username,
email: email,
wwid: wwid,
country: country,
geo: geo,
// userid: '',
};
// Check if user exists in DB
await res.locals.connection.query('SELECT * FROM users WHERE username = ?', [app.locals.UserData.username], async function (error, results, fields) {
if (error) throw error;
// Get the Current Date-Time for insertion
const accessDateTime = new Date();
const adtYear = accessDateTime.getFullYear();
const adtMonth = accessDateTime.getMonth() + 1;
const adtDay = accessDateTime.getDate();
const adtHour = accessDateTime.getHours();
const adtMin = accessDateTime.getMinutes();
const adtSec = accessDateTime.getSeconds();
const dts = `${adtYear}-${adtMonth}-${adtDay} ${adtHour}:${adtMin}:${adtSec}`;
// If results is empty, then the user who just logged in does not currently have
// an account provisioned, so set them up an account.
if (!(results.hasOwnProperty(0))) {
await res.locals.connection.query('INSERT INTO users SET ?', {first_name: app.locals.UserData.firstName, middle_name: app.locals.UserData.middleName, last_name: app.locals.UserData.lastName, username: app.locals.UserData.username, email: app.locals.UserData.email, status: 1, created: dts, access: dts, login: dts}, async function (ierror, iresults, ifields){
if (ierror) throw ierror;
app.locals.UserData.userid = 22;
// app.locals.UserData.userid = iresults.insertID;
});
} else {
await res.locals.connection.query('UPDATE users SET login = ?, access = ? WHERE uid = ?', [dts, dts, results[0].uid], async function (ierror, iresults, ifields){
if (ierror) throw ierror;
app.locals.UserData.userid = 44;
// app.locals.UserData.userid = results[0].uid;
});
}
});
// Set User Session Cookie
res.cookie('UserData', app.locals.UserData);
// Set SAML Session Cookie
setCookie(res, req, sessionID);
// Get the referrer location
var refererLocation = req.cookies.referLocation;
// If it is undefined, then send the user back to where they started the Sign On process.
if (refererLocation != undefined) {
res.clearCookie("referLocation");
res.redirect('https://www.example.com' + refererLocation);
} else {
res.redirect('https://www.example.com/uri');
}
next();
});
});
Рабочий код
Спасибо DMFAY и BennetQuigley. Эта проблема была решена.
Рабочий раствор прокомментирован ниже.
app.post('/api/v1/saml/acs', function (req, res, next) {
const options = {
request_body: req.body,
allow_unencrypted_assertion: true
};
sp.post_assert(idp, options, function (err, saml_response) {
if (err)
res.redirect('https://www.example.com/');
// Get the Sessions ID
const sessionID = saml_response.response_header.id;
// Set the returned User Info to a Variable
const user = saml_response.user.attributes;
// Set the app.locals.UserData variable
app.locals.UserData = {
firstName: user.givenName,
middleName: null,
lastName: user.sn,
username: user.uid,
email: user.mail,
wwid: user.employeeID,
country: user.country,
geo: user.geographicRegion,
};
// Check if user exists in DB
res.locals.connection.query('SELECT * FROM users WHERE username = ?', [app.locals.UserData.username], function (error, results, fields) {
if (error) throw error;
// Get the Current Date-Time for Insert/Update of user logon history
const accessDateTime = new Date();
const adtYear = accessDateTime.getFullYear();
const adtMonth = accessDateTime.getMonth() + 1;
const adtDay = accessDateTime.getDate();
const adtHour = accessDateTime.getHours();
const adtMin = accessDateTime.getMinutes();
const adtSec = accessDateTime.getSeconds();
const dts = `${adtYear}-${adtMonth}-${adtDay} ${adtHour}:${adtMin}:${adtSec}`;
// If results is empty, then the user who just logged in does not currently have
// an account provisioned, so set them up an account.
if (!(results.hasOwnProperty(0))) {
res.locals.connection.query('INSERT INTO users SET ?', {
first_name: app.locals.UserData.firstName,
middle_name: app.locals.UserData.middleName,
last_name: app.locals.UserData.lastName,
username: app.locals.UserData.username,
email: app.locals.UserData.email,
status: 1,
created: dts,
access: dts,
login: dts
}, function (ierror, iresults, ifields){
if (ierror) throw ierror;
// set the app.locals.UserData.userid value to the newly inserted ID
app.locals.UserData.userid = `["${iresults.insertID}"]`;
// From here to 'next()' has to be repeated in both cases
// 'next()' must be used to return the values and actions to the parent
// Call.
// Set User Session Cookie
res.cookie('UserData', app.locals.UserData);
// Set SAML Session Cookie
setCookie(res, req, sessionID);
// Get the referrer location
var refererLocation = req.cookies.referLocation;
// If it is undefined, then send the user back to where they started the Sign On process.
if (refererLocation != undefined) {
res.clearCookie("referLocation");
res.redirect('https://clpstaging.mcafee.com' + refererLocation);
} else {
res.redirect('https://clpstaging.mcafee.com/clp');
}
// Tell the callback to move forward with the actions.
next();
});
} else {
res.locals.connection.query('UPDATE users SET login = ?, access = ? WHERE uid = ?', [dts, dts, results[0].uid], function (ierror, iresults, ifields){
if (ierror) throw ierror;
// Set the app.locals.UserData.userid to the Users PK
app.locals.UserData.userid = results[0].uid;
// From here to 'next()' has to be repeated in both cases
// 'next()' must be used to return the values and actions to the parent
// Call.
// Set User Session Cookie
res.cookie('UserData', app.locals.UserData);
// Set SAML Session Cookie
setCookie(res, req, sessionID);
// Get the referrer location
var refererLocation = req.cookies.referLocation;
// If it is undefined, then send the user back to where they started the Sign On process.
if (refererLocation != undefined) {
res.clearCookie("referLocation");
res.redirect('https://www.example.com' + refererLocation);
} else {
res.redirect('https://www.example.com/uri');
}
// Tell the callback to move forward with the actions.
next();
});
}
});
});
});