当json网络令牌过期时,如何使用React / Redux登出

如何解决当json网络令牌过期时,如何使用React / Redux登出

我为React创建了中间件,可以检测JSON Web令牌何时过期。我想注销用户并将其令牌过期后将其重定向到我的应用程序的主页。

我正在工作的中间件如下:

const jwt_decode = require("jwt-decode");

const checkTokenExpirationMiddleware = store => next => action => {
  const token = localStorage.getItem("token");
  if (jwt_decode(token).exp < Date.now() / 1000) {
    next(action);
    localStorage.clear();
    console.log("token middleware was fired");
  }
  next(action);
};

module.exports = checkTokenExpirationMiddleware;

但是我希望它看起来像以下功能-问题是我无法导入redux操作或redux存储。注意:我使用“ connected-react-router”通过历史记录重定向用户。

const jwt_decode = require("jwt-decode");
import { push } from "connected-react-router";   // this results in an error
import { logout } from "../actions/authActions.js";   //this results in an error

const checkTokenExpirationMiddleware = store => next => action => {
  const token = localStorage.getItem("token");
  if (jwt_decode(token).exp < Date.now() / 1000) {
    next(action);
    localStorage.clear();
    console.log("token middleware was fired");
    store.dispatch(logout());   // I can't do this because I can't import
     store.dispatch(push("/"));

  }
  next(action);
};

module.exports = checkTokenExpirationMiddleware;

我的商店

import rootReducer from "./reducers/index";
import { createStore,applyMiddleware,compose } from "redux";
import { connectRouter,routerMiddleware } from "connected-react-router";
import thunk from "redux-thunk";
import tokenCheck from "./ReduxCustMiddleware/tokenCheck";

import { history } from "./history";

const middleware = [tokenCheck,thunk,routerMiddleware(history)];
const enhancer = compose(
  applyMiddleware(...middleware),window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

const store = createStore(connectRouter(history)(rootReducer),enhancer);

export default store;

我的令牌是在我的登录帖子路径中创建的。

const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const config = require("config");
const jwt = require("jsonwebtoken");
const auth = require("../../middleware/auth");

// User Model
const User = require("../../models/User");

// @route GET api/auth
//@desc Authenticate user
// @access Public
router.post("/",(req,res) => {
  const { email,password } = req.body;

  if (!email || !password) {
    return res.status(400).json({ msg: "Please enter all fields" });
  }

  // Check for existing user
  User.findOne({ email }).then(user => {
    if (!user) return res.status(400).json({ msg: "User does not exist" });

    // Validate password
    bcrypt.compare(password,user.password).then(isMatch => {
      if (!isMatch) return res.status(400).json({ msg: "Invalid credentials" });

      jwt.sign(
        { id: user.id },config.get("jwtSecret"),{ expiresIn: 3600 },(err,token) => {
          if (err) throw err;
          res.json({
            token,user: {
              id: user.id,name: user.name,email: user.email
            }
          });
        }
      );
    });
  });
});

// @route GET api/auth/user
//@desc Get user data using token
// @access Private
router.get("/user",auth,res) => {
  User.findById(req.user.id) //req.user is the token... the id property was attached to the token above
    .select("-password") //says to not include the password when returning user data
    .then(user => res.json(user));
});

module.exports = router;

我的令牌通过我的身份验证操作发送到我的redux reducer

import axios from "axios";
import store from "../store";
import { returnErrors } from "./errorActions";
import {
  USER_LOADED,USER_LOADING,AUTH_ERROR,LOGIN_SUCCESS,LOGIN_FAIL,LOGOUT_SUCCESS,REGISTER_SUCCESS,REGISTER_FAIL
} from "./types";
import { push } from "connected-react-router";

// Check token & load user
export const loadUser = () => (dispatch,getState) => {
  // User loading
  dispatch({ type: USER_LOADING });

  axios
    .get("/api/auth/user",tokenConfig(getState))
    .then(res =>
      dispatch({
        type: USER_LOADED,payload: res.data
      })
    )
    .catch(err => {
      dispatch(returnErrors(err.response.data,err.response.status));
      dispatch({
        type: AUTH_ERROR
      });
    });
};

// Register User
export const register = ({
  name,email,password,confirm_password
}) => dispatch => {
  //Headers
  const config = {
    headers: {
      "Content-Type": "application/json"
    }
  };

  //Request body
  const body = JSON.stringify({ name,confirm_password });

  axios
    .post("/api/users",body,config)
    .then(res =>
      dispatch({
        type: REGISTER_SUCCESS,payload: res.data
      })
    )

    .catch(err => {
      dispatch(
        returnErrors(err.response.data,err.response.status,"REGISTER_FAIL")
      );
      dispatch({
        type: REGISTER_FAIL
      });
      store.dispatch(push("/"));
    });
};

// Login User
export const login = ({ email,password }) => dispatch => {
  //Headers
  const config = {
    headers: {
      "Content-Type": "application/json"
    }
  };

  //Request body
  const body = JSON.stringify({ email,password });

  axios
    .post("/api/auth",config)
    .then(res =>
      dispatch({
        type: LOGIN_SUCCESS,"LOGIN_FAIL")
      );
      dispatch({
        type: LOGIN_FAIL
      });
      store.dispatch(push("/"));
    });
};

// Logout User
export const logout = () => {
  return {
    type: LOGOUT_SUCCESS
  };
};

// Setup config/headers and token
export const tokenConfig = getState => {
  //Get token from localstorage
  const token = store.getState().auth.token;

  //Headers
  const config = {
    headers: {
      "Content-type": "application/json"
    }
  };

  // If token,add to headers
  if (token) {
    config.headers["x-auth-token"] = token;
  }

  return config;
};


它保存在我的reducer中的本地内存中

import {
  USER_LOADED,REGISTER_FAIL
} from "../actions/types";

const initialState = {
  token: localStorage.getItem("token"),isAuthenticated: null,isLoading: false,user: ""
};

export default function(state = initialState,action) {
  switch (action.type) {
    case USER_LOADING:
      return {
        ...state,isLoading: true
      };
    case USER_LOADED:
      return {
        ...state,isAuthenticated: true,user: action.payload
      };

    case LOGIN_SUCCESS:
    case REGISTER_SUCCESS:
      localStorage.setItem("token",action.payload.token);

      return {
        ...state,...action.payload,isLoading: false
      };
    case AUTH_ERROR:
    case LOGIN_FAIL:
    case LOGOUT_SUCCESS:
    case REGISTER_FAIL:
      localStorage.removeItem("token");
      return {
        ...state,token: null,user: null,isAuthenticated: false,isLoading: false
      };
    default:
      return state;
  }
}


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-