【问题标题】:How to protect routes on a client server with JWT generated from my RESTful backend API?如何使用从我的 RESTful 后端 API 生成的 JWT 保护客户端服务器上的路由?
【发布时间】:2018-10-29 04:18:39
【问题描述】:

我正在尝试使用 Nodejs 构建注册/登录应用程序。通过查看这些文章,我了解到这是一个很好的结构来设计您的应用程序,以便您的后端实际上是一个 RESTful API,并且您的客户端可以访问该 API。 (客户端和服务器都运行在不同的服务器上,而客户端只是一个普通的旧静态文件服务器)。

现在一切都很顺利,直到我不得不让用户登录。当访问具有特定数据的 API 端点 (/signin) 时,数据会根据数据库进行验证,如果好的,我正在签署 JSON Web 令牌并传递它随着客户。

但问题在于,这样,我只能保护我的 API 上的路由,即我只能强制用户必须登录才能访问特定的后端 API 端点。

但是我可以做些什么来使用这个 JWT 对我的客户端强制执行相同的操作?例如,如果在我的客户端中有dashboard.html,并且我希望只有登录用户可以访问它,那么用户可以继续生成JWT。但是这个 JWT 在限制客户端路由方面是如何发挥作用的呢?

我的登录路线:

app.post('/signin', (req, res) => {
var data = req.body;

if (!exists(data.username) || !exists(data.password))
    return res.status(422).json({
        message: 'All fields are required'
    });

const users = db.get('users');
users
    .findOne({
        username: data.username,
        password: shajs('sha256').update(data.password).digest('hex')
    })
    .then((user) => {
        if (user) {
            jwt.sign({
                _id: user._id,
                username: user.username
            }, 'keyboard_cat', {
                expiresIn: '1h'
            }, (err, tok) => {
                return res.status(200).json({
                    message: 'OK',
                    token: tok
                });
            });
            return;
        }

        return res.status(200).json({
            message: 'Invalid Username or Password.'
        })
    });
});

【问题讨论】:

  • JWT 只能在后端验证。因此,您可能希望在客户端加载标记之前通过 API 调用检查 JWT 的有效性。
  • @tbking 所以基本上我也必须在我的客户端上启动另一个节点服务器?正确的?因为正如我现在所说,它只是一个静态文件服务器,除了提供文件之外什么都不做?
  • 这取决于您的实现,但静态 javascript 文件可以调用 Node.js API 服务器。不需要另一台服务器。发布 JWT 的 API 服务器只能验证 JWT。客户端 javascript 需要访问 API 服务器。
  • @tbking 如果它只是一个会调用 Node API 的客户端 js 文件,那么用户是否无法获取该 js 文件并进行更改,但他想访问静态受保护的路由? (因为必须在浏览器中执行客户端 js 文件,因此客户端可以更改它以访问客户端上的受保护路由)

标签: node.js routing jwt


【解决方案1】:

您可以在前端使用条件渲染。您可以使用 api 令牌(从 '/signin' api 生成)触发 api,它会在您输入路由时告诉您 api 令牌是否有效。
根据服务器对令牌的响应,您可以决定要呈现哪个页面(正常页面或未经授权的页面)。

还有一个更好的方法,在header中的每个路由中发送api令牌,如果令牌格式错误或无效,则从后端返回401错误。全局捕获这个错误(或者你可以使用axios提供的响应拦截器)然后进行条件渲染。

【讨论】:

  • 但是对于所有这些,我也需要在我的客户端服务器上使用节点,这是有道理的。但是,如果我必须在客户端和服务器上都使用节点,那么将它们分开有什么意义呢?之前我认为客户端仍然是一个静态文件服务器(没有节点,没有 php,只是一个普通服务器),但现在很明显,要进行客户端路由保护,我需要节点将令牌发送到后端进行验证?
  • 显然客户端服务器应该提供静态文件。您不需要渲染 html 页面并通过网络发送该页面。使用像 React 这样的框架的单页应用程序,他们使用这种类型的策略来决定只在客户端打开哪个页面。您必须在 express 中编写后端中间件,以检查和验证每个路由上的 JWT 令牌。同样可以在客户端完成。它可以通过使用钩子来实现,当你的路线改变时应该触发它。
猜你喜欢
  • 2019-12-02
  • 2021-08-27
  • 2014-07-21
  • 2017-10-16
  • 2021-02-20
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2023-02-13
相关资源
最近更新 更多