【发布时间】:2021-12-07 06:10:01
【问题描述】:
我的登录用户有问题,当我刷新页面时,用户迷路了。这就是我分配 JWT 令牌的方式:
const signToken = id => {
return jwt.sign({ id }, 'my-ultra-secure-and-ultra-long-secret', {
expiresIn: '14d',
});
};
这也是我使用此函数向 cookie 发送令牌的方式:
const createSendToken = (user, statusCode, res) => {
const token = signToken(user._id);
const cookieOptions = {
expires: new Date(Date.now() + 14 * 1000 * 60 * 24),
httpOnly: true,
};
res.cookie('jwt', token, cookieOptions);
// Remove password from output
user.password = undefined;
res.status(statusCode).json({
status: 'success',
token,
data: {
user,
},
});
};
这是我的登录控制器:
exports.login = catchAsync(async (req, res, next) => {
const { email, password } = req.body;
// 1) Check if email and password exist
if (!email || !password) {
return next(new AppError('Please provide email and password!', 400));
}
// 2) Check if user exists && password is correct
const user = await User.findOne({ email }).select('+password');
if (user && (await user.correctPassword(password, user.password))) {
createSendToken(user, 200, res);
} else {
return next(new AppError('Incorrect email or password', 401));
}
});
这是我的 Protect 控制器(保护中间件):
exports.protect = catchAsync(async (req, res, next) => {
// 1) Getting token and check of it's there
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith('Bearer')
) {
token = req.headers.authorization.split(' ')[1];
}
if (!token) {
return next(
new AppError('You are not logged in! Please log in to get access.', 401)
);
}
// 2) Verification token
const decoded = await promisify(jwt.verify)(
token,
'my-ultra-secure-and-ultra-long-secret'
);
// 3) Check if user still exists
const currentUser = await User.findById(decoded.id);
if (!currentUser) {
return next(
new AppError(
'The user belonging to this token does no longer exist.',
401
)
);
}
// 4) Check if user changed password after the token was issued
if (currentUser.changedPasswordAfter(decoded.iat)) {
return next(
new AppError('User recently changed password! Please log in again.', 401)
);
}
// GRANT ACCESS TO PROTECTED ROUTE
req.user = currentUser;
res.locals.user = currentUser;
next();
});
这是我使用这个中间件的私有路由:
router.route('/:id').get(authController.isLoggedIn, postController.getPost);
问题是当我登录时我得到一个 cookie,但我无法访问受保护的路由(我得到一个错误令牌未定义)。当我刷新页面时,用户丢失了,但 cookie 仍在存储中。当我尝试通过邮递员访问保护路由并将授权承载添加到标题时.....(令牌)我可以访问它。
这是我的前端用户减速器:
export const userLoginReducer = (state = {}, action) => {
switch (action.type) {
case USER_LOGIN_REQUEST:
return { loading: true, isAuthenticated: false };
case USER_LOGIN_SUCCESS:
return {
loading: false,
isAuthenticated: true,
user: action.payload,
};
case USER_LOGIN_FAIL:
return { loading: false, isAuthenticated: false, error: action.payload };
case USER_LOGOUT:
return { loading: false, isAuthenticated: false, user: null };
default:
return state;
}
};
这是我的用户操作:
export const login = (email, password) => async dispatch => {
try {
dispatch({
type: USER_LOGIN_REQUEST,
});
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const { data } = await axios.post(
'/api/v1/users/login',
{ email, password },
config
);
dispatch({
type: USER_LOGIN_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: USER_LOGIN_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
这是我的登录屏幕:
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const redirect = location.search ? location.search.split('=')[1] : '/';
const dispatch = useDispatch();
const userLogin = useSelector(state => state.userLogin);
const { loading, error, isAuthenticated } = userLogin;
console.log(isAuthenticated);
useEffect(() => {
if (isAuthenticated) {
history.push(redirect);
}
if (error) {
console.log(error);
}
}, [isAuthenticated, history, redirect, error]);
const submitHandler = e => {
e.preventDefault();
dispatch(login(email, password));
};
我在这里停留了大约 2 天,试图完成这个。请有人帮助我:)
【问题讨论】:
标签: node.js reactjs redux jwt mern