gpt4 book ai didi

node.js - express 请求.isAuthenticated

转载 作者:行者123 更新时间:2023-12-04 03:44:31 26 4
gpt4 key购买 nike

我的 Express 应用程序调用 request.isAuthenticated() 方法。但是,我不知道它检查什么来确定它是否经过身份验证。我的应用需要通过 OIDC 进行身份验证。如何告诉 isAuthenticated() 方法它通过了 OIDC 身份验证?
目前,我已将其设置为使用适当的 client_id 范围重定向到 OIDC 授权端点。用户的浏览器跟随重定向,用户成功登录。OIDC 将重定向发送回我的 Express 应用程序提供的回调。用户浏览器成功到达此端点。
我的合并文件在下面的一篇文章中。因为我是 Node 新手,所以它比我想要的更草率。此外,因为我无法让 Visual Code 捕获我的断点(请参阅我的其他相关帖子),我只能使用 console.log 语句进行调试。
如果我在浏览器中转到/cost-recovery,它会转到这条路线:

  app.use('/cost-recovery*', saveUrlInSession, /*ensureAuthenticated*/ isLoggedIn,createProxyMiddleware(sprint_cost_recovery_options));
它将 URL 保存在 session 中,允许回调到我想要的地方。这样可行。在 ensureAuthenticated 和 isLoggerdIn 处理程序中,系统重定向到 OIDC/OpenId/??身份证登录页面。我能够登录,它会返回到我的回调页面。在那个回调路由中, req.isAuthenticated() 仍然是假的。
也许是因为我正在使用这个护照模块,所以它不知道登录发生了。设置了 cookie,在紧要关头,我可以检查那些来代替有效的 req.isAuthenticated() 方法,但我宁愿使用提供的工具。
/**
* How the application respond to clients requests depending of the endpoint
*/
const userController = require('../controllers/userController');
var OpenIDConnectStrategy = require('passport-ci-oidc').IDaaSOIDCStrategy;
const strategyConfiguration = require('../../config/strategy.json');
console.log('strategyConfiguration=' + JSON.stringify(strategyConfiguration));
const passport = require('passport');
const https = require('https');
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {

console.log('App setting title=' + app.get('title'));
console.log('App env=' + app.get('env'));

console.log('App setting query parser=' + app.get('query parser'));
console.log('App setting string routing=' + app.get('strict routing'));
console.log('App setting case sensitive routing=' + app.get('case sensitive routing'));


var http = require('http');

var url = require('url');

var currentOriginalUrl;

passport.serializeUser(function (user, done) {
done(null, user);
});

passport.deserializeUser(function (obj, done) {
done(null, obj);
});

// openid-client is an implementation of the OpenID Relying Party (RP, Client) server
// for the runtime of Node.js, support passport

//OAuth 2.0 protocol
//middleware Passport-OpenID Connect
const config = require('../configuration/config').getConfiguration();
console.log('config=' + JSON.stringify(config));
console.log('strategyConfiguration=' + JSON.stringify(strategyConfiguration));

var OpenIDConnectStrategy = require('passport-ci-oidc').IDaaSOIDCStrategy;
var Strategy = new OpenIDConnectStrategy({
discoveryURL: strategyConfiguration.discoveryURL,
clientID: strategyConfiguration.clientID,
scope: 'openid',
response_type: 'code',
clientSecret: strategyConfiguration.clientSecret,
callbackURL: strategyConfiguration.callbackURL,
skipUserProfile: true, /* this was true before */
CACertPathList: [
`/certs/DigiCertGlobalRootCA.crt`,
`/certs/DigiCertSHA2SecureServerCA.crt`,
]
},
function (iss, sub, profile, accessToken, refreshToken, params, done) {
process.nextTick(function () {
profile.accessToken = accessToken;
profile.refreshToken = refreshToken;

const userDetails = profile._json;
const userProfile = {
uid: userDetails.uid,
mail: profile.id,
cn: decodeURIComponent(userDetails.cn),
exp: 60 * 60 /*TODO: Get proper number of seconds. userDetails.exp */,
blueGroups: userDetails.blueGroups,
};
done(null, userProfile);

})
}
)

var proxy_server = require('http-proxy').createProxyServer({});

const originalUrl = new URL(config.host);
console.log('matched cost-recovery using original url: ' + originalUrl);
const newUrl = new URL(originalUrl);
newUrl.port = 8447;
console.log('matched cost-recovery new url' + newUrl);


function saveUrlInSession(request, response, next) {
if (request.params.state) {
console.log('Saving state=' + request.params.state + " in session");
request.session.savedUrl = request.request.params.state;
} else {
console.log('Saving originalUrl=' + request.originalUrl + " in session");
request.session.savedUrl = request.originalUrl;
}
if (next) {
return next();
} else {
console.log('@@ no next');
}
}

function ensureAuthenticated(req, res, next) {
if (!req.isAuthenticated()) {
console.log('@@ ensureAuthenticated reached. Not authenticated. redirecting to /login');
res.redirect('/login')
} else {
console.log('@@ ensureAuthenticated reached. Authenticated. Continuing to next handler');
return next();
}
}

function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
console.log('@@isLoggedIn req.isAuthenticated()=true');
req.session.isAuthenticated = true;
res.locals.isAuthenticated = true;
res.locals.user = req.user;
next(); //If you are authenticated, run the next
} else {
console.log('@@isLoggedIn req.isAuthenticated()=false');
return res.redirect("/login");
}
}

function getUserProfile(req, res, next) {
console.log('@@ reached getUserProfile')
if (typeof req.user == 'undefined') {
res.status(401);
next();
}
return res.status(200).send(req.user);
}

function getUserName(req, res, next) {
console.log('@@ reached getUserName')
if (typeof req.user === 'undefined') {
res.status(401);
return next();
}
return res.status(200).send(req.user.cn);
}

var newURL = url.format({
protocol: config.protocol,
host: config.host,
pathname: config.originalUrl
});

console.log('newURL=' + newURL);
var newURL2 = new URL(newURL);
newURL2.port = "8447";
newURL2.protocol = "http";
console.log('newURL2=' + newURL2);
const sprint_cost_recovery_options = {
target: newURL2,
level: 'debug',
changeOrigin: true,
ws: true
}
console.log('@@ sprint_cost_recovery_options=' + JSON.stringify(sprint_cost_recovery_options));

passport.use(Strategy);

app.use(passport.initialize());
app.use(passport.session());
app.use(function (request, response, next) {
console.log('Common Route: Incoming request originalUrl:' + request.originalUrl);
console.log('Common Route: Incoming request previous Url:' + request.header('referer'));
console.log('Common Route: Incoming request url:' + request.url);
next();
});


app.get('/auth/sso/callback/:callback_uri?'
, function (request, response, next) {
console.log('CB-1 matched on originalUrl=' + request.originalUrl);
console.log('@@ CB-2. isAuthenticated=' + request.isAuthenticated());
console.log('@@ CB-2.5 request.account test=' + request.account);
console.log('@@ savedUrl in session=' + request.session.savedUrl);
//var redirectUrl = poppedUrlFromSession(request);
var redirectUrl = request.session.savedUrl;
if (!redirectUrl) {
redirectUrl = "/health-check";
}
console.log('@@ CB-3. redirectUrl=' + redirectUrl);
console.log('@@ CB-4. before passport.authenticate');
console.log('@@ CB-5. after passport.authenticate');
console.log('@@ CB-6. isAuthenticated=' + request.isAuthenticated());
console.log('@@ auth-sso-callback-2 bp1');
response.redirect(redirectUrl);

}
);

app.use('/login?:state?',
function (request, response, next) {
var stateIndicator = (request.params.state) ? " with state " + request.params.state : " with no state/redirect.";
console.log('@@ Reached login with ' + stateIndicator);
return next();
},
passport.authenticate('openidconnect', { state: Math.random().toString(36).substr(2, 10) }));

app.use('/rules/username', saveUrlInSession, ensureAuthenticated, userController.getUserName);

app.use('/rules/profile', saveUrlInSession, ensureAuthenticated, userController.getUserProfile);

app.use('/cost-recovery*', saveUrlInSession, /*ensureAuthenticated*/ isLoggedIn,createProxyMiddleware(sprint_cost_recovery_options));

app.use('/profile', saveUrlInSession, ensureAuthenticated, getUserProfile);

app.use('/username', saveUrlInSession, ensureAuthenticated, getUserName);

app.get('/successful-login', function (req, res) {
res.send('login succeeded');
});

app.get('/failure', function (req, res) {
res.send('login failed');
});

app.get('/health-check', (request, response) => {
response.send('Middleware is running.');
});

};

最佳答案

简短的回答是大部分时间req.isAuthenticated只是检查值是否 req.user已设置,但详细信息可能会根据您的 Passport 配置而改变。
我想你可能已经很清楚了,isAuthenticated方法被添加到 req对象 Passport.js .
对于reasons that don't seem clear to anyone else ,该方法似乎没有任何面向公众的文档。
但是你可以找到req.isAuthenticated的实现(也是 req.isUnauthenticated )在护照的 http/request.js 的来源中.
原始代码目前是这样的:

req.isAuthenticated = function() {
var property = 'user';
if (this._passport && this._passport.instance) {
property = this._passport.instance._userProperty || 'user';
}

return (this[property]) ? true : false;
};
( Lines 77-90 在我查看的版本 request.js 中。)
正如你所看到的,这个基本实现本质上是(1)找出护照的 userProperty。设置为和 (2) 检查是否 req[userProperty]是“真实的”。
( userProperty 值是 Passport 的另一个记录不足或可能未记录的功能。您可能只是假设该值为 user,除非您已采取措施使其成为其他内容。)
如此有效 isAuthenticated应该返回 true如果 req.user已设置为非空对象和 false如果 req.usernullfalse0 , ETC。
您可能知道,在一般情况下,护照策略将设置 req.user作为 req.login 一部分的已验证用户的属性映射函数(由 passport.authenticate 中间件间接调用)。所以通常在你调用 req.login 之后或 passport.authenticate你应该期待 req.user被填充,因此对于 req.isAuthenticated返回真。
由于这没有发生,我的猜测是其中之一正在发生。
  • login函数或 authenticate中间件实际上并没有在您期望的时候被调用。
  • 正在调用该函数,但身份验证本身失败(因此 isAuthenticated() === false 在技术上是正确的)。
  • 认证成功但配置文件信息未保存为req.user .

  • 在已知登录后检查请求对象可能会清楚是否存储了用户信息,如果是,存储在哪里。
    扫描您共享的代码,您似乎还希望在 req.user 中找到用户配置文件信息对于您的应用程序,所以如果这一切正常,我希望 req.isAuthenticated工作,但我不确定我是否完全了解你的整体状况。
    我不熟悉 password-ci-oidc特别是(虽然我在 npm 上看到了该模块,但看起来原始源代码并不公开),但您可能想深入了解 req.useruserProperty它正在使用和/或是否正在填充用户对象。
    特别是 skipUserProfile: true你的策略配置中的一点点在我身上跳出来。是否有可能您实际上是在告诉策略中间件不要填充 req.user ?
    与您最初的问题无关,另一件需要注意的是 req.isAuthenticated()没有做太多 req.user ? true : false因此,如果您有一种更可靠的方法来验证用户是否已通过身份验证,则只需使用它就足够了(或猴子补丁 req.isAuthenticated 以使用您的逻辑而不是默认行为)。无论如何,它似乎并没有做更多的事情。

    关于node.js - express 请求.isAuthenticated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65387843/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com