使用相同的操作清除并重置本地存储中用户的 JWT 令牌
Posted
技术标签:
【中文标题】使用相同的操作清除并重置本地存储中用户的 JWT 令牌【英文标题】:Clear and reset user's JWT token in local storage with same action 【发布时间】:2021-11-19 03:39:10 【问题描述】:我正在制作一个组件,用户可以在其中更改他们的详细信息,而我这样做的方式是他们实质上是在删除他们的帐户并重新创建它 - 使用 Redux 和 JWT 进行此操作。如果有更好的方法,请告诉我,但现在这对我来说是个窍门。
当用户首次创建帐户时,它会在本地存储中使用正确的详细信息设置其 JWT 令牌。这很好用。当他们登录时,它也设置它没有问题。
问题在于,当他们调用“编辑”功能,删除他们的帐户并创建一个新帐户时,上述情况并没有发生。因此,如果我使用用户名“aaa”创建一个帐户,应用程序会使用配置文件的键和我创建的值来显示该帐户。但是当我调用编辑它时 - 例如用户名“bbb”,即使一个新帐户 is 成功创建(显示在我的 MongoDB 中,可以登录),它是 not 正确更新令牌 - 键的值显示为 的空对象。
有没有一种简单的方法来清除然后更新我丢失的令牌?很想帮忙!
我的行动在这里:
import * as api from "../api";
import AUTH, DELETE from "./ActionTypes";
export const signin = (formData, history) => async (dispatch) =>
try
const data = await api.signIn(formData)
dispatch( type: AUTH, data )
history.push("/");
catch (error)
console.log(error);
;
export const signup = (formData, history) => async (dispatch) =>
try
const data = await api.signUp(formData)
dispatch( type: AUTH, data )
history.push("/");
catch (error)
console.log(error);
;
export const editProfile = (formData, history) => async (dispatch) =>
try
const data = await api.editProfile(formData)
const data2 = await api.signUp(formData)
Promise.resolve(dispatch( type: DELETE, data )).then(
() => dispatch( type: AUTH, data2 ))
history.push("/profile");
catch (error)
console.log("error here", error);
;
我的减速器在这里:
import AUTH, LOGOUT, EDIT, REFRESH from "../actions/ActionTypes";
const authReducer = (state = authData: null , action) =>
switch (action.type)
case AUTH:
localStorage.setItem('profile', JSON.stringify(...action?.data));
return ...state, authData: action.data;
break;
case LOGOUT:
localStorage.clear()
return ...state, authData: null;
return state;
break;
case EDIT:
localStorage.clear()
return ...state, authData: null;
default:
return state;
break;
;
export default authReducer;
我的项目的 GitHub 在这里:https://github.com/gordonmaloney/lingr-mern/
(顺便说一句,在放弃并来到 Stack Overflow 询问之前,我花了一整天的时间试图弄清楚如何修补细节,但是当我输入我的问题时,我突然意识到我可以尝试通过删除和重新创建来做到这一点,我现在非常接近将它放在我想要的地方,最后这个小颠簸真的让我感到沮丧!)
【问题讨论】:
【参考方案1】:你在这里有一点 Promises 眩晕。让我们探索editProfile
函数,特别是这个位:
Promise.resolve(dispatch( type: DELETE, data )).then(/* ... */)
我会在Promise.resolve()
引用文档:
Promise.resolve() 方法返回一个已解析的 Promise 对象 给定值
而dispatch()
本身返回一个Promise
。所以,你在这里所做的是将dispatch
返回的一个promise 包装成另一个promise,立即通过调用Promise.resolve()
解决这个“外部”promise,然后你正在调度AUTH
动作。
你应该做的是:
dispatch( type: DELETE, data )).then(() => dispatch( type: AUTH, data2 ));
或者,在我看来更好读:
await dispatch( type: DELETE, data );
await dispatch( type: AUTH, data2 );
history.push("/profile");
这意味着您将等待dispatch
完成,然后调用第二次调度。
【讨论】:
嗯,这对我来说是同样的事情 - 它仍然成功地删除了旧帐户并创建了一个新帐户,但是在它运行之后 localStorage 仍然像以前一样显示 。 如果你根本不给dispatch( type: DELETE )
打电话怎么办?看起来 dispatch( type: AUTH, data2 )
应该为您解决问题,因为它会重写 localStorage 上的数据
我刚刚解决了问题 - 导致问题的是“data2”,所以我对其进行了更改,因此在 AUTH 操作和编辑操作中它被称为相同,现在它工作得很好,尽管我怀疑如果不进行您最初建议的更改就不会发生,所以非常感谢您!【参考方案2】:
我解决了!
这是因为两个 reducer 都在寻找 action.data,这就是最初调用注册操作的方式。但是因为它在作为编辑操作的一部分被调用时被称为“data2”,所以它没有找到任何可以更新令牌的东西。我更改了名称,现在它可以正常工作了。
供参考,新代码如下:
动作:
import * as api from "../api";
import AUTH, DELETE from "./ActionTypes";
export const signin = (formData, history) => async (dispatch) =>
try
const data = await api.signIn(formData)
dispatch( type: AUTH, data )
history.push("/");
catch (error)
console.log(error);
;
export const signup = (formData, history) => async (dispatch) =>
try
const data = await api.signUp(formData)
dispatch( type: AUTH, data )
history.push("/");
catch (error)
console.log(error);
;
export const editProfile = (formData, history) => async (dispatch) =>
try
const data2 = await api.editProfile(formData)
const data = await api.signUp(formData)
await dispatch( type: DELETE, data2 );
await dispatch( type: AUTH, data );
history.push("/profile");
catch (error)
console.log(error);
;
减速器:
import AUTH, LOGOUT, EDIT, REFRESH from "../actions/ActionTypes";
const authReducer = (state = authData: null , action) =>
switch (action.type)
case AUTH:
localStorage.setItem('profile', JSON.stringify(...action?.data));
console.log(action)
return ...state, authData: action.data;
break;
case LOGOUT:
localStorage.clear()
return ...state, authData: null;
break;
case EDIT:
localStorage.clear()
localStorage.setItem('profile', JSON.stringify(...action?.data2));
return ...state, authData: null;
default:
return state;
break;
;
export default authReducer;
【讨论】:
以上是关于使用相同的操作清除并重置本地存储中用户的 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章