如何知道用户是否使用passport.js登录?


104

我已经阅读passport.js了两天的信息和样本,但不确定此后是否完成了所有身份验证过程。

我怎么知道我是否已登录,例如,我将有一个带有登录或注销按钮的导航栏,下面是否有一些变量,如代码?

if (login)
   <button>logout</button>
else 
   <button>login</button>

Answers:


210

如果用户已登录,passport.js将为userreq的每个请求创建一个对象express.js,您可以检查任何中间件是否存在:

if (req.user) {
    // logged in
} else {
    // not logged in
}

您可以express.js为此创建简单的中间件,该中间件将检查用户是否已登录,如果没有,则将重定向到/login页面:

function loggedIn(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

并使用它:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});

是全球性的吗?登录后可以在所有项目中访问它吗?
RMontes13 2013年

3
它不是全局的,只是在请求对象上。
2013年

1
在使用express.js和passport.js进行98.8%的Web开发中,您将处理请求(app.get,app.post等),因此谈论在其外部使用passport.js毫无意义。是的,它是只在快递航线中间件处理程序一样app.getapp.post等等。如果你需要不同的功能,那么你应该解释一下它在细节在你的问题以及你要实现的目标。
moka 2013年

2
我发现,如果我不为router.get()提供任何用于验证身份验证的中间件,例如“ router.get('/',my_controller.index)”,那么就不会查阅护照,而req.user将始终未定义。这令人沮丧,因为我想允许任何访问者调用API,但根据谁在请求来定制响应的内容。
劳伦斯·西恩

2
有人可以解释这是如何无法利用的吗?该检查只是看它们是否是请求中的用户对象。会话验证在哪里?
rambossa

46

如果您想在模板中使用它,因为您的代码示例似乎表明您可以创建一些中间件,例如:

app.use(function (req, res, next) {
  res.locals.login = req.isAuthenticated();
  next();
});

设置护照后,将代码放置在某处。

然后在模板中使用它(swig示例)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}

由于某种原因,上述中间件给我一个问题,因为我的模板中的用户未定义。我必须为视图重新提供用户对象,以进行如下修复: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers

即使在成功认证之后,isAuthenticated在下一个请求中也给出false。你能帮助回答这个问题stackoverflow.com/questions/42842171/...
Suhail古普塔

3

它没有明确记载,但是有一种通过护照isAuthenticated()插入的方法。 可以如下使用,req

req.isAuthenticated() // returns true if auth, false if not

// auth.js
module.exports = {
  ensureAuthenticated: (req, res, next) => {
    if (req.isAuthenticated()) {
      return next()
    }
    res.redirect('/login') // if not auth
  },

  forwardAuthenticated: (req, res, next) => {
    if (!req.isAuthenticated()) {
      return next()
    }
    res.redirect('/dashboard');  // if auth    
  }
}

// app.js
app.get('/dashboard', ensureAuthenticated, (req, res) => res.render('dashboard'))
app.get('/login', forwardAuthenticated, (req, res) => res.render('login'))
app.get('/register', forwardAuthenticated, (req, res) => res.render('register'))

2

我正在搜索这样的解决方案,并偶然发现了该页面。问题是如何在客户端检查登录状态。

登录后,我隐藏“登录”按钮并显示“注销”按钮。在页面刷新时,我再次看到登录按钮而不是注销按钮。唯一的解决方案是,如果使用会话,则将项目保存在sessionStorage中(如果使用JWT,则将其保存在localStorage中)。注销时删除此项目。然后在每个页面加载中检查此sessionStorage项目并进行相应的操作。

if (sessionStorage.getItem('status')) {
    $("#btnlogout").show();
    $("#btnlogin").hide();
// or what ever you want to do
} else {
    $("#btnlogout").hide();
    $("#btnlogin").show();
}



function Login() {
            var data = {
                username: $("#myModal #usr").val(),
                password: $("#myModal #pw").val()

            };
            $.ajax({
                type: 'POST',
                url: '/login',
                contentType: 'application/JSON; charset=utf-8',
                data: JSON.stringify(data),
                success: funcSuccess,
                error: funcFail
            });
            function funcSuccess(res) {
                sessionStorage.setItem('status', 'loggedIn');

                $("#btnlogout").show();
                $("#btnlogin").hide();
            }
            function funcFail() { $("#pp").text('Login Failed'); };
        };

function Logout() {
    $.ajax({
        type: 'GET',
        url: '/logout',
        contentType: 'application/JSON; charset=utf-8',
        success: funcSuccess,
        error: funcFail,
    });
    function funcSuccess(res) {
        $("#btnlogout").hide();
        $("#btnlogin").show();
        sessionStorage.removeItem("status");
    };
    function funcFail() { alert('Login method Failed'); };
}; 

2

在app.get()或router.get()中使用以下代码

router.get('/edit/:id', (req, res)=>{
  if(req.isAuthenticated()){
     if(req.isAuthenticated()){
      //

      }
  else{
   res.redirect('/users/login');//your particular login routes
     }
});

0

很好的问题,我在尝试实现类似问题时遇到了一些问题,当存在未经身份验证的请求时,如果res.locals变量返回假值,则把手将跳过if块。要解决此问题,您需要在app.js文件中设置中间件,以使req.user在您的应用程序中全局可用。

app.use(function (req, res, next) {
res.locals.login = req.user;
next();

});

在您的头文件中,您可以对经过身份验证的用户执行此检查,并根据类似内容显示内容。

                {{#if login }}
                    <li><a href="#">User Account</a></li>
                    <li role="separator" class="divider"></li>
                    <li><a href="#">Logout</a></li>
                {{/if}}
                {{#unless login}}
                    <li><a href="#">Sign up</a></li>
                    <li><a href="#">Sign in</a></li>
                {{/unless}} 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.