如何使用 fetch 在前端存储和处理 JWT 令牌,以及如何存储它?
Posted
技术标签:
【中文标题】如何使用 fetch 在前端存储和处理 JWT 令牌,以及如何存储它?【英文标题】:How to store and handle JWT tokens on front-end using fetch, and how to store it? 【发布时间】:2020-11-18 08:35:16 【问题描述】:我是开发新手,我有一个任务管理器应用程序,我在其中使用 JWT 令牌进行验证,我可以让它在 Postman 上运行,但我不知道如何通过浏览器存储它并发送它到服务器。
这是我试图使其工作的方法,但它在事件侦听器之外显示未定义,并且我无法存储令牌以稍后将其发送到另一个 url,我正在将令牌发送到 API。
这是我的前端 app.js 代码,用于登录页面,登录时会向用户发送一个 JWT 令牌:
let inMemoryToken;
const signInForm = document.querySelector( "#sign-in-form" );
signInForm.addEventListener( "submit", ( e ) =>
const email = document.querySelector( "#login-email" ).value;
const password = document.querySelector( "#login-pass" ).value;
e.preventDefault();
console.log( email, password );
fetch( "http://localhost:3000/users/login",
method: 'post',
headers:
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
,
body: JSON.stringify(
"email": email,
"password": password,
)
).then( res => res.json() )
.then( res =>
console.log( res );
let inMemoryToken = res.token;
console.log( inMemoryToken );
// Authorization: `Bearer $ inMemoryToken `;
return inMemoryToken;
);
console.log( inMemoryToken );
return inMemoryToken;
);
// inMemoryToken = res.body.token[ 0 ];
// let inMemoryToken2 = inMemoryToken;
console.log( inMemoryToken );
我的登录后台代码是:
router.post( "/users/login", async ( req, res ) =>
try
const user = await User.findByCredentials(
req.body.email,
req.body.password
);
const token = await user.generateAuthToken();
res.send(
user,
token,
);
catch ( e )
res.status( 400 ).send(
error: "Catch error",
e,
);
);
另外,在得到这个令牌后,我想把它传递给我的任务 url,它是:
const TaskForm = document.querySelector( "#add-tasks" );
TaskForm.addEventListener( "submit", ( e ) =>
const task = document.querySelector( '#task' ).value;
e.preventDefault();
console.log( task );
console.log( inMemoryToken );
fetch( "http://localhost:3000/tasks/",
method: 'get',
headers:
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'Authorization': 'Bearer $inMemoryToken'
,
body: JSON.stringify(
"Task": task
)
).then( res => res.json() )
.then( res => console.log( res ) );
);
我从 3 天开始一直在尝试解决此问题,但无法使其正常工作,我们将不胜感激。
【问题讨论】:
【参考方案1】:要将 JWT 存储在客户端,您有两种选择:Cookies
或 LocalStorage
策略。我想你已经知道 cookie 是什么了。 LocalStorage 与 cookie 非常相似,但经过增强并且无需在标头中发送信息(请参阅Mozilla Developer definition),这就是为什么 LocalStorage 通常用作持久对象的原因。
服务器 端保持不变。无需更改。
在您的客户端上,在 登录处理程序 响应中,您将在 LocalStorage 中存储来自后端的响应,如下所示:
signInForm.addEventListener( "submit", ( e ) =>
. . .
fetch( "http://localhost:3000/users/login",
. . .
).then( res => res.json() )
.then( res =>
console.log( res );
let inMemoryToken = res.token;
localStorage.setItem('user', JSON.stringify(res));
// 'user' is the generic key to sotre in LocalStorage. You could use any name you want
// Store complete object, so you will be able to access 'user' and 'token' later
在你的任务函数上,你应该为你的对象阅读LocalStorage
const TaskForm = document.querySelector( "#add-tasks" );
TaskForm.addEventListener( "submit", ( e ) =>
const task = document.querySelector( '#task' ).value;
e.preventDefault();
console.log( task );
// ------ This is what you have to add --------
const localstorage_user = JSON.parse(localStorage.getItem('user'))
const inMemoryToken = localstorage_user.token
// -------------------------------------------
console.log( inMemoryToken );
【讨论】:
感激不尽,我真的很难弄清楚这一点。十分感谢。另外,您能否告诉我为什么我的授权传递在此代码中不起作用:jsfiddle.net/mx7cg03w/1 如果您觉得它有用,请接受答案 :-) 您还有什么问题?您的评论没有提供代码?您指的是您问题的代码吗? 抱歉,您的链接没有显示。我去看看 对不起,我已经在jsfiddle上添加了代码,请你看看。 嗯。我认为是'
字符。试试:Bearer $inMemoryToken
以上是关于如何使用 fetch 在前端存储和处理 JWT 令牌,以及如何存储它?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 vue 中存储、管理 REST API JWT 身份验证令牌?