javascript - 如何使用 fetch 在前端存储和处理 JWT 令牌,以及如何存储它?
问题描述
我是开发新手,我有一个任务管理器应用程序,我在其中使用 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 天开始解决这个问题,但无法让它工作,任何帮助将不胜感激。
解决方案
要将 JWT 存储在客户端上,您有两个选择:Cookies
或LocalStorage
策略。我想你已经知道 cookie 是什么了。LocalStorage 与 cookie 非常相似,但经过增强且无需在标头中发送信息(请参阅Mozilla 开发人员定义),这就是为什么 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 );
推荐阅读
- java - 来自文件的二维字符数组
- java - 如何使用 java 处理 tar gz 中的文件
- ios - 由于未定义的符号而无法构建 ios 应用程序:_OBJC_CLASS_$_GADRewardBasedVideoAd
- python - 我收到 Travis CI 构建错误“未找到模块”,但我不知道为什么
- python - 使用 Python 学习自动化,并且对这段代码有疑问。也许另一双眼睛?
- python - 如何在函数外部访问在函数内部创建的特定变量。即使该函数中有多个其他变量
- node.js - MongoDB GridFs:grid.mongo.ObjectID 不是构造函数
- python-3.x - 来自 Django 模板中来自同一父级的其他子级的访问列
- latex - 在单独的 .yaml 文件中添加 header-includes 和 fancyhdr “breaks” pandoc
- mysql - 如果日期不为空或为空,如何获取开始日期和到期日期之间的数据?