【问题标题】:Check if Axios has a session cookie检查 Axios 是否有会话 cookie
【发布时间】:2020-11-01 22:47:02
【问题描述】:

我正在为我的 Vue.js 应用程序实现导航保护,检查用户是否登录。我认为最好的方法是询问 Axios 是否有会话 cookie。像这样的:

router.beforeEach((to, from, next) => {
  if (Vue.axios.hasSessionCookie())
    next()
  else
    next(false);
}

当然,hasSessionCookie() 不存在,而且我在文档中也没有看到类似的东西。有没有办法,也许通过某种扩展?

是的,我知道我可以将登录状态存储在 VueX 商店中。我认为这不是一个好主意,因为如果用户以其无限的智慧刷新页面并因此重置应用程序,则状态将重置。我想到的另一个解决方案是应用程序可以“询问”是否已登录的后端端点。但这也很蹩脚。

【问题讨论】:

  • 首先如何设置cookie?是来自使用 document.cookies 的客户端 cookie 吗?
  • 这是一个来自 Node.js / Express 后端的会话 cookie。 Axios 捕获它并且会话有效。但是好像没办法问axios有没有session cookie。
  • 如果是服务器端会话cookie,则无法从客户端javascript检查它,您需要向您的快速服务器发出额外的HTTP请求以检查服务器端会话cookie 有效/存在。
  • 你的意思是没有办法验证它。我不想验证,只检查会话是否存在。这是一个前端导航守卫,不是关键的东西。
  • 您可以通过开发者控制台在您的 Web 上尝试 console.log(document.cookie) 并查看您的 cookie 值是否存在吗?

标签: vue.js axios


【解决方案1】:

感谢您提供的所有提示。正确的解决方案如下:

  • VueX 存储导航守卫检查的登录状态(只是一个布尔标志)
  • 当用户登录或注销时,我设置了标志
  • 当应用启动时,我在创建 Vue 实例之前调用服务器上的/checklogin 路由。这只是根据用户是否具有有效会话返回 200 或 401 状态代码。然后我相应地设置了 VueX 标志。这样用户可以刷新浏览器,但 VueX 仍然会知道他是否已登录。
  • 另外我添加了一个 Axios 拦截器来检测 401 错误。如果有,则表示会话已过期。然后它将 VueX 标志设置为 false 并将用户重定向到登录页面。

如果有人关心,我在我的 Medium 博客上写了一篇文章,其中包含详细信息和 sn-ps。 https://medium.com/developer-rants/session-management-between-express-and-axios

【讨论】:

    【解决方案2】:

    由于它是服务器端 cookie,您无法在客户端 javascript 上检查它,您需要向您的 express 服务器发出 HTTP 请求以检查会话是否存在。在您的快速服务器上创建一个简单的路由,如下所示:

    app.get("/checkcookie", function(req,res) {
        if (req.session.yourSessionVariableName) {
            res.status(204).send();
        } else {
            res.status(401).send();
        }
    });
    

    然后检查你的 vue 导航守卫:

    router.beforeEach(async (to, from, next) => {
      const response = await axios.get("http://yourexpressbackend.com/checkcookie");
      if (response.status === 204)
        next()
      else
        next(false);
    }
    

    【讨论】:

    • 这就是我现在正在做的事情。但这不是一个很好的解决方案:每次用户更改路由时都会额外调用一次 HTTP,这意味着服务器会增加额外的负担,并且也会降低应用程序的速度。我想我正在解决在 VueX 商店中存储一个标志,每当 Axios 收到 401 时,将其设置为 false。
    • 如果你想像你说的那样在客户端检查它,你需要“弗兰肯斯坦”一点。看看this,因为它可能有用。如果您想要一个好的解决方案来检查客户端的用户身份验证,那么您需要使用将您的身份验证信息(令牌、JWT 等)存储在客户端,如 localStorage 或客户端 cookie。
    • 谢谢,我想我已经找到了解决方案。我要写一篇关于它的文章。
    【解决方案3】:

    您的方向是正确的,但 axios 是一个 HTTP 客户端,它与 cookie 无关,也不关心 cookie 或存储。所以您需要使用像 vue-cookies 这样的包来设置和获取 cookie。

    【讨论】:

    • 唉,这无济于事。 IDK Axios 对 cookie 做了什么,但是会话 cookie 没有出现在开发者工具中,也无法用 vue-cookies 读取。后端肯定会提供它。
    【解决方案4】:

    Tamás Polgár,您记录了我在使用 Vue 时遇到的完全相同的挑战;如果发生意外的浏览器事件并且商店丢失,如何登录。

    Vue 商店:

    Vue 存储是 SPA 存储此类标志(登录或未登录)的方便位置,但是,存储被完全擦除并随着每个 Vue 实例重新建立,这意味着一个新的浏览器窗口/ 选项卡、刷新或其他触发浏览器刷新的意外事件。

    因此,您的方法描述了一个额外的后端调用来快速检查状态,这是一个合法且可行的 IMO 解决方案。

    还有另外两个潜在的解决方案,其中第二个是我在自己的 SPA 中实现的:

    另外两种解决方案

    1) 完全不要触碰您的后端代码。建立登录后,使用vue-cookies 让客户端浏览器设置 cookie(这将与后端 API 服务器所需的仅 http cookie 完全分开)。

    此 cookie应该在浏览器刷新后仍然存在。但是,我没有使用(或尝试)这种方法,因为我不想在每次要检查登录状态时都更改前端以检查本地 cookie。

    前端代码可以使用这个 cookie 来判断这个人是否仍然登录。

    2) 另一种单独的方法是短路正常的后端 API 检查以进行身份​​验证仅针对该特定路由的控制器,而不针对任何其他路由.

    后端“短路”的工作原理如下:

    对于该特定路由的控制器方法,让它首先检查请求中是否存在用户,然后返回 200,但状态为“false”或其他一些变量也出现在成功响应。

    这是违反直觉的,但这给前端 Axios 调用提供了一些可以抓取的东西,而不仅仅是标准错误响应。

    注意:我称其为“短路”,因为如果后端 API 路由的控制器方法有很多代码,那么首先检查它会避免代价高昂的部分来电。

    这种方法非常适合我的需求,不需要新的或辅助 API 调用。

    【讨论】:

    • 确实检查后端有点违反直觉,但就在今年的情况下,我有一种感觉,我们早就放弃了优雅和流畅编码等概念.特别是在 Javascript 世界中。
    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 2011-03-26
    • 2023-03-12
    • 2015-02-07
    相关资源
    最近更新 更多