如何使用Axios将JWT存储在cookie中?

时间:2019-02-12 14:46:51

标签: javascript reactjs cookies jwt axios

我在React应用程序和Axios中使用JWT处理API调用。我正在寻找一种将令牌存储在cookie中的方法,这样就不会在每次刷新浏览器时都将我重定向到另一次登录。

这是我的Axios设置和登录电话:

let authToken = null; 

const axios = axiosAPI.create({
    baseURL: baseURL
});

// User login
export const loginUser = (data) => {
    return new Promise((resolve, reject) => {
        axios.post(`${baseURL}/jwt-auth/v1/token`, data)
            .then((res) => {
                authToken = res.data.token;

                // Adds the token to the header
                axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;

                resolve(res.data);
            })
            .catch((error) => {
                reject(error);
            });
    });
};

我不确定应该在哪里设置cookie以及如何设置它?

编辑:

我已使用js-cookie重写了代码,因此看起来像是注释。

import axiosAPI from 'axios';
import Cookies from 'js-cookie';

let authToken = null;

const axios = axiosAPI.create({
    baseURL: `${baseURL}`
});

// Check if user is logged in.
(function () {
    if (Cookies.get('token') === null) {
        // This means that there's no JWT and no user is logged in.
        axios.defaults.headers.common.Authorization = null;
    } else {
        // This means that there's a JWT so someone must be logged in.
        axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
    }
}());

// User login
export const loginUser = (data) => {
    return new Promise((resolve, reject) => {
        axios.post(`${baseURL}/jwt-auth/v1/token`, data)
            .then((res) => {
                authToken = res.data.token;

                Cookies.setToken('token', authToken);

                // Adds the token to the header
                axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;

                resolve(res.data);
            })
            .catch((error) => {
                reject(error);
            });
    });
};

但是,这完全使我无法登录,并且出现错误“段数错误”。知道为什么这行不通吗?

1 个答案:

答案 0 :(得分:1)

您可以在此处采用几种不同的方法来解决所遇到的问题,它们只是找到可以存储JWT的位置,以便即使刷新页面也可以使用它。

  1. 将JWT保存在axios.post回调的 localStorage sessionStorage 中,以便即使刷新页面后也可以访问它。要了解哪种存储最适合您的应用,请参阅this

    为简短起见,存储在 localStorage 中的值将一直保留,直到您明确删除它们为止(您可以通过JS代码执行此操作)。另外,您在浏览器中打开的到该域的任何选项卡都可以访问此选项卡(如果您仍然希望使用新选项卡登录,则非常有用)。另一方面,存储在 sessionStorage 中的值仅在选项卡关闭之前有效。它们也不能跨标签共享。

    使用此方法非常简单:
    localStorage.setItem("JWT", authToken);

    之后的回调中的sessionStorage.setItem("JWT", authToken);authToken = res.data.token;

    因此,现在您有了一个存储JWT的位置,您需要做的就是确保在应用程序在页面加载(或刷新)时初始化时,检查存储中是否存在JWT。这是如何使用localStorage的基本示例:

// This should be one of the first things that run on your app.

const axios = axiosAPI.create({
    baseURL: baseURL
});

// Check if user is logged in.
(function() { 
  let authToken = localStorage.getItem("JWT");
  if (authToken === null) {
      // This means that there ISN'T JWT and no user is logged in.
      axios.defaults.headers.common.Authorization = null;
  } else {
      // This means that there IS a JWT so someone must be logged in.
      axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
  }
})();

这将确保用户(如果先前已登录)不会在页面加载时注销。

  1. 将JWT保存在客户端cookie 中。在这里,由于您的身份验证都是围绕JWT构建的,因此您实际上并未使用服务器端cookie,因此cookie被用作存储机制。您可以遵循与上述相同的代码模式,但是将使用document.cookie = "key=value"设置cookie,并使用document.cookie查看所有 cookie。

    第二种方法不太常见,因为它会迫使您执行大量的人工操作,例如解析所有cookie,并确保设置正确的cookie path属性,以便仅根据需要发送cookie。端点(否则您只会造成不必要的开销)。如果您使用此选项,请阅读this,以帮助您创建适合您需要的cookie。 您还可以使用js-cookie之类的辅助JS库来帮助操作客户端Cookie。

此外,我将通读https://stackoverflow.com/a/40376819/11048825,以进一步探讨这两个选项,并了解与每个选项相关的利弊。