如何解决当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 举报,一经查实,本站将立刻删除。