javascript - 在反应应用程序中检查 JWT 过期
问题描述
所以我创建了这些上下文来处理登录用户并将登录用户检索到可能需要它的任何组件。
他们来了:
context.js
import React, { useReducer } from "react";
import { AuthReducer, initialState } from "./reducers";
const AuthStateContext = React.createContext();
const AuthDispatchContext = React.createContext();
export function useAuthState() {
const context = React.useContext(AuthStateContext);
if (context === undefined) {
throw new Error("useAuthState must be used within a AuthProvider");
}
return context;
}
export function useAuthDispatch() {
const context = React.useContext(AuthDispatchContext);
if (context === undefined) {
throw new Error("useAuthDispatch must be used within a AuthProvider");
}
return context;
}
export const AuthProvider = ({ children }) => {
const [user, dispatch] = useReducer(AuthReducer, initialState);
return (
<AuthStateContext.Provider value={user}>
<AuthDispatchContext.Provider value={dispatch}>
{children}
</AuthDispatchContext.Provider>
</AuthStateContext.Provider>
);
}
reducers.js
let user = localStorage.getItem("currentUser")
? JSON.parse(localStorage.getItem("currentUser")).user
: "";
let token = localStorage.getItem("currentUser")
? JSON.parse(localStorage.getItem("currentUser")).token
: "";
export const initialState = {
userDetails: user || "",
token: token || "",
loading: false,
errorMessage: null,
};
export const AuthReducer = (initialState, action) => {
switch (action.type) {
case "REQUEST_LOGIN":
return {
...initialState,
loading: true,
};
case "LOGIN_SUCCESS":
return {
...initialState,
userDetails: action.payload.user,
token: action.payload.token,
loading: false,
};
case "LOGOUT":
return {
...initialState,
userDetails: "",
token: "",
};
case "LOGIN_ERROR":
return {
...initialState,
loading: false,
errorMessage: action.error,
};
default:
throw new Error(`Unhandled action type: ${action.type}`);
}
};
actions.js
const ROOT_URL = process.env.REACT_APP_API_HOST_URL;
export async function loginUser(dispatch, loginPayload) {
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(loginPayload),
};
try {
dispatch({ type: "REQUEST_LOGIN" });
let response = await fetch(`${ROOT_URL}/auth/login`, requestOptions);
let data = await response.json();
if (data.user) {
dispatch({ type: "LOGIN_SUCCESS", payload: data });
localStorage.setItem("currentUser", JSON.stringify(data));
return data;
}
dispatch({ type: "LOGIN_ERROR", error: data.errors[0] });
return;
} catch (error) {
dispatch({ type: "LOGIN_ERROR", error: error });
}
}
export async function logout(dispatch) {
dispatch({ type: "LOGOUT" });
localStorage.removeItem("currentUser");
localStorage.removeItem("token");
}
我的问题是如何扩展它以检查每次useAuthState()
调用钩子时 JWT 是否已过期(如果这甚至是最好的处理方式)?然后将用户注销或从服务器刷新令牌,而无需尽可能将用户注销。
提前致谢。
解决方案
推荐阅读
- javascript - 猫头鹰旋转木马 - 在导航按钮中间放置一个图像计数器
- qt - 如何借助布局在 QGraphicWidget 中排列小部件和形状?
- node.js - Mongo Change Streams running multiple times (kind of): Node app running multiple instances
- coldfusion - 在 ColdFusion 查询中添加 AND 语句
- r - 将矩阵中的每一行除以向量中的对应行
- ibm-watson - 训练 ibm watson 发现
- ios - Apple Watch:这是让 Apple Watch 应用获取新数据的好方法吗?
- javascript - vue-cli v3 与 node.js firebase 函数,firebase 托管(错误:在函数源目录中找不到 npm 包)
- python - 将值附加到python字典中的键
- php - PHP 通过 URL 传递一个单独的表值