护照 isAuthenticated() 总是返回 TRUE

5

使用本地身份验证方法登录成功后,我点击getStatus按钮也能成功获取结果,之后退出也没有问题。但是,退出后如果我在浏览器中点击“返回”按钮,就能看到完整的getStatus内容。而isAuthenticated()中的控制台日志仍然显示“您已登录”。以下是简化代码:

var express    = require('express');
var passport   = require('passport');
var net        = require('net');
var bodyParser = require('body-parser');
var http       = require('http');
var multer     = require('multer');
var cp         = require('child_process');
var exec       = require('child_process').exec;
var sys        = require('sys');
var path       = require('path');
var util       = require('util');
var session    = require('express-session');

var crypto     = require('crypto');
var sqlite3    = require('sqlite3');

/////////////////////////////////////////////////
var LocalStrategy = require('passport-local').Strategy;
var db = new sqlite3.Database('./myPassword.db');

passport.use(new LocalStrategy(function(username, password, done)
{
    console.log("step 2: Client sent you user: " + username + " password: " + password);

    db.get('SELECT slat FROM users WHERE username = ?', username, function(err, row)                                  
    {
        if (!row) return done(null, false);
        console.log("step 4");

        db.get('SELECT username, id FROM users WHERE username = ? AND password = ?',
               username, password, function(err, row) 
        {
            console.log("step 6");

            if (!row) return done(null, false);

            console.log("step 8");

            return done(null, row);
        });
    });
}));

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


passport.deserializeUser(function(id, done) {
    db.get('SELECT id, username FROM users WHERE id = ?', id, function(err, row)
    {
        if (!row) 
            return done(null, false);
        return done(null, row);
    });
});

/////////////////////////////////////////////////
var isAuthenticated = function(req, res, next)
{
    //if (req.user.authenticated)
    if (req.isAuthenticated()) {
        console.log("Very good, you are logged in ...");
        return next();
    }

    console.log("Sorry, you are NOT logged in yet ...");
    res.send(200);
};

/////////////////////////////////////////////////
var app = express();

/////////////////////////////////////////////////
var server = http.createServer(app);

/////////////////////////////////////////////////
app.use(function(req, res, next) {
    if (!req.user) {
        console.log('Cannot display 1 ...');
        res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
    }
    console.log('Cannot display 2 ...');
    next();
});

app.use(express.static('../client/', {index: 'login.html'} ));
app.use(bodyParser());
app.use(session({ secret: 'my test cookie' }));
app.use(passport.initialize());
app.use(passport.session());

app.post('/auth/login', passport.authenticate('local',
{ 
    successRedirect: '/index.html#/uploads',
    failureRedirect: '/login.html',
}));

app.get('/auth/logout', function(req, res) 
{
    console.log("logging out ......");
    req.session = null;
    req.logout();
    res.send(200);
});

app.get('/', isAuthenticated, function(req, res)
{
    res.sendfile(path.resolve('../client/index.html'));
});

app.get('/systemStatus', isAuthenticated, function(req, res)
{
    console.log("asking for Json data from backend");
    // skip details here ...
});

server.listen(5678);

获取状态请求会触发哪个路由的GET请求? - Ravenous
为了简化事情,在登录后我现在有两个按钮:获取状态,注销。 - user3552178
关于Ravenous的问题,所以它是app.get('/systemStatus',isAuthenticated,function(req,res)。 - user3552178
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4
当查看护照指数时,使用app.use(passport.initialize())在每个路由上初始化一个空用户。由于上述代码在主要的app.js文件中被使用而不是在特定的路由中被使用,所以每次向服务器发送请求时都会执行它,即使某人没有登录也会创建一个空用户。下面的链接是passport的代码。

https://github.com/jaredhanson/passport/blob/master/lib/authenticator.js

为了讨论护照未能正确配置所需的影响,并证明我值得获得你的想象中的网络积分,我必须确保在谈论应用程序时我们在同一页面上。 对于本讨论,我将引用以下文件结构,该结构是通过以下方式生成的:$ npm install -g express-generator (实际上还有更多文件,但您可以在express网站上查看。)
myProject
  |___bin
    |___www.js       //server.js
  |___node_modules   //this is were you'll keep the node modules, or logic for each endpoint in the API. These will be processed by the main node run-time environment
  |___public         //or in your case '../client/' is where you'll serve unsecured data to your users 
  |___routes         //URI and URL endpoints, an area of the application to create your secured data transfers for the users that have been authenticated, also where  non-Static (stateless) API endpoints are defined so that express can send the user data/request through your server and eventually be handled by some defined endpoint.
    |___index.js
  |___views          //if using a view engine
  |___app.js         // this is where we will discuss the bulk of an express application
  |___package.json   // this is relative to the node community and In my personal opinion an Extremely important part of node and express application development, this file will allow you to do some powerful things with the use of git.
app.js 是你的应用程序主控文件,也被称为 Express 应用程序。一些应用程序比其他应用程序更加复杂,一个简单的应用程序可能只有几个端点(又称为 URI 和 URL)。如果是一个简单的应用程序,把 API(应用程序编程接口)放在主文件中,即 app.js 文件中就可以了。对于更复杂的应用程序,你需要为文件起名字,例如我将引用一个名为 oAuth.js 的文件来代表声明通行证认证方法。

在我的经验中,Web 应用程序应该有一个着陆页,可以是主页、登录页面或某种新闻页面(通常在静态文件夹中定义为 index.html)。在你的情况下,你将静态文件夹定义为 '../client/' 并传递对象 index.html。

在最新版本的 Express 4.X 中,提供静态文件服务的方式如下所述。

使用Express内置的中间件express.static可以完成提供文件(如图片、CSS、JavaScript和其他静态文件)的功能。将需要标记为静态资源位置的目录名称传递给express.static中间件即可直接开始提供文件服务。例如,如果您将图像、CSS和JavaScript文件保存在名为public的目录中,则可以执行以下操作: Express生成器将创建以下已配置非常重要的app.js文件。这个第一部分有一些非常有用的node模块,它们是与express无关的,最终您将导入自己的一些node API。
var express = require('express'),
path = require('path'), //core node module
logger = require('morgan'), //allows you to see the console.logs during development and see incoming and outgoing messages to the server. It also displays `console.log()` defined in any node_module, express route, and express app file.
cookieParser = require('cookie-parser'), //helps when trying to handle cookies
bodyParser = require('body-parser');   //helps when parsing certain types of data 
路由就像迷你的 Express 应用程序,还记得我们第一次讨论有些应用程序比其他应用程序更复杂吗?这就是如何管理复杂性,使您的应用程序可以不断增长和繁荣。假设您希望为您可爱而美妙的用户添加新功能。
var route = require('.routes/index',// this is importing the the logic of the URI and URL enpoint to this file. It will be referenced as the second argument in the route and configuration references below.
    oAuth = require('.routes/oauth') // this is the file where you'll place all of the passport logic you have previously wrote. Any other authenticated routes need to be defined in this file.

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); //alot of people are also using EJS equally if not more
现在设置由express-generator提供的基本中间件。
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));  //this style  declaration ensures you hit what ever directory you want to by changing public as long as that directory exists. 
路由URI和URL端点是由您定义到express的。它采用字符串形式,并在此文件顶部引用其路由。
app.use('/', routes); //unsecured landing page 
这个 Express 对象的用法可以帮助你定义 API,授权和未授权的路由。在这里,你将声明对 Express 应用程序的身份验证部分的引用。在 app.use('/auth/',oAuth) 上方声明的应用程序部分将不会被验证。在你的 URI 和 URL 的 /auth/ 部分以下声明的任何部分都将被验证。
app.use('/auth/', oAuth);  
一些额外的内容会由Express生成器放置在应用程序文件中,这些内容非常有用。
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});
由于您在应用程序命名空间中引入了不必要的复杂性,这无意中导致了不良的身份验证影响。这更深层次地涉及到格式化和配置应用程序编程接口以及如何在Node运行时环境中执行JavaScript文件,以及构建需要身份验证才能访问的复杂应用程序时,express应用程序框架的使用和配置方式。 现在回到您提出的问题:为什么即使没有用户登录,您仍然获得已认证的用户?这是因为您使用了app.use('some string or some middleware')。要解决此问题,请删除所有身份验证处理并将其移动到路由中。在上面的示例中,它被引用为oAuth.js。将需要身份验证的任何路由定义在passport中间件后面。 现在因为您的问题也涉及到节点,并且您在评论中提到您是 scrum的一部分,所以重要的是要说明所有这些信息都包含在 express website上,这也是我最初链接我的答案的地方。尽管我告诉过您需要一条路由并且passport配置不正确。所以任何激烈的评论“读手册”都是因为我觉得您甚至没有调查我在最初答案中发送的链接,也没有阅读express框架和他们网站的任何其他部分。如果您计划了解任何node_modules和复杂的框架,同样重要的是要阅读它们并完成它们的教程,当有入门和/或它们有API参考时实际浏览node_modules。在没有尝试过框架基础知识的情况下进入应用程序开发只会让您花费更多时间编写不好的易于破坏的代码。如果您不了解node_modules的功能,它将显着减慢您的开发速度。了解其功能的最佳方法是阅读它们。这就是我关于学习如何开发Web应用程序的抱怨/建议。最终,您将能够在应用程序中重复使用很多您的教程代码。

非常感谢您的回复,我被匆忙地安排到这个项目中,没有时间学习,基本上是在赶进度时即兴编写代码,他们称之为Scrum?您能否直接告诉我解决方案吗?我只有一个用户使用此网页。无论如何,谢谢! - user3552178
@user3552178 我已经告诉了你解决方案,你在主应用程序中初始化了一个空用户。去了解一下路由是什么以及如何将它们整合到 Express 中。http://expressjs.com/guide/routing.html - Ravenous
叹气,如果我能理解你的解决方案,我就不会问了,谢谢! - user3552178
顺便说一下,我正在遵循这个例子http://stackoverflow.com/questions/28346746/browser-back-button-doesnt-destroy-the-session-in-passportjs-expressjs-how-t - user3552178
@user3552178 嘿,你不笨,这对我也是一个学习经验。我对我认为可以接受的答案有期望,但这有助于我学习如何更好地解释事情,以便其他人也能学习和理解。 - Ravenous
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,