如何使用 Axios 将 JWT 存储在 cookie 中?
Posted
技术标签:
【中文标题】如何使用 Axios 将 JWT 存储在 cookie 中?【英文标题】:How can I store a JWT in cookies using Axios? 【发布时间】:2019-07-06 06:05:01 【问题描述】:我在我的 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);
);
);
;
但是,这完全阻止了我登录,并且我收到错误“段数错误”。知道为什么这不起作用吗?
【问题讨论】:
您不能在 Ajax 调用中设置 cookie。看看我的老问题How to modify Cookie from Ajax call 【参考方案1】:您可以在此处采用几个不同的选项来解决您遇到的问题,即简单地找到存储 JWT 的位置,以便您即使在刷新页面后也可以使用它。
将 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`;
)();
这将确保用户不会在页面加载时退出(如果之前已登录)。
将 JWT 保存在 客户端 cookie 中。在这里,cookie 被用作存储机制,因为您实际上并没有使用服务器端 cookie,因为您的身份验证都是围绕 JWT 构建的。您可以遵循与上述相同的代码模式,但将使用 document.cookie = "key=value"
设置 cookie 并使用 document.cookie
查看 所有 cookie。
第二种方式不太常见,因为它迫使你做大量的体力劳动,比如解析所有的 cookie 并确保设置正确的cookie path
属性,以便只为所需的端点发送 cookie (否则你只是在创造不必要的开销)。如果您使用此选项,请阅读 this 以帮助您创建 cookie 以满足您的需求。 您还可以使用像 js-cookie 这样的辅助 JS 库来帮助操作客户端 cookie。
此外,我会通读 https://***.com/a/40376819/11048825 以进一步深入研究这两个选项,并了解每个选项的优缺点。
【讨论】:
尝试使用您的代码并使用 js-cookie 设置和获取 cookie。我已经编辑了原始帖子以显示我的新代码。知道为什么它不起作用吗? @G.Cox - 啊,我意识到我将Bearer $authToken
分配给页面加载时的axois 授权标头,而authToken
甚至没有在该匿名函数中定义。我已经纠正了我上面的错误。通过在匿名函数中的 if/else 语句之前执行 let authToken = Cookies.get('token');
之类的操作,确保在代码中执行相同的操作。
@G.Cox - 此外,您的代码中还有另一个错字。而不是Cookies.setToken('token', authToken)
,应该是Cookies.set('token', authToken);
请勿使用 localStorage 或 sessionStorage 存储令牌,因为它们会暴露给 javascript,因此很容易受到跨站点脚本攻击。以上是关于如何使用 Axios 将 JWT 存储在 cookie 中?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 vue 中存储、管理 REST API JWT 身份验证令牌?