node.js - Heroku API 无法访问 cookie
问题描述
我在 heroku 上托管了一个 JWT auth API。从我的前端 React 应用程序使用 axios 访问 API 时,我注意到受保护的路由永远无法获取,因为它们依赖于从未设置的 res.cookies。在 postman 上测试 API 时,它设置了 cookie,一切正常。你能帮我找出哪里出了问题,以及如何克服这个问题。
需要这个 cookie,因为当我 GET /user 时,使用以下代码:
exports.checkUser = catchAsync(async (req, res, next) => {
let currentUser;
if (req.cookies.jwt) {
const token = req.cookies.jwt;
const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);
currentUser = await User.findById(decoded.id);
} else {
currentUser = null;
}
res.status(200).send({ currentUser });
});
currentUser 应按如下方式填充
当我使用我的反应前端访问这个 API 时:这是我的 useAuth 钩子
import { useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import axios from "axios";
import { UserContext } from "./userContext";
export default function useAuth() {
let history = useHistory();
const { setUser } = useContext(UserContext);
const [error, setError] = useState(null);
const setUserContext = async () => {
return await axios
.get("<my api link>/user")
.then((res) => {
console.log(res);
setUser(res.data.currentUser);
history.push("/home");
})
.catch((err) => {
console.log(err);
setError(err);
});
};
const registerUser = async (data) => {
const { username, email, password, passwordConfirm, name } = data;
return axios
.post("<My api link>/auth/post", {
username,
email,
password,
passwordConfirm,
name,
})
.then(async (res) => {
console.log(res);
await setUserContext();
})
.catch((err) => {
console.log(err);
return setError(err);
});
};
res.data.currentUser 始终为空。任何帮助表示赞赏
解决方案
JWT 的概念是将令牌的处理交给客户端。
因此,前端应该存储/保存它在 cookie 中接收到的 JWT 令牌,或者应该通过在您想要访问此类受保护路由的请求中localstorage
发送它们。headers
因此,这是前端职责,这就是 Postman 自动为您处理它的原因。
您可以在需要时使用react-cookie在前端保存和检索此 JWT 令牌,并且您必须重新修改您的axios
请求。
在您的特定情况下,您可以对 GET 请求执行以下操作:
axios.get('URL', {
withCredentials: true
});
但我强烈建议修改您的后端以从headers
cookie 中提取 JWT 令牌,这将使您的请求类似于:
let JWTToken = 'xxyyzz'; // Get this from cookie or localstorage, hardcoded for demonstration.
axios
.get("URL", { headers: {"Authorization" : `Bearer ${JWTToken}`} })
.then(res => {
this.profile = res.data;
console.log('Fetched Data is', res.data);
})
.catch(error => console.log(error))
不要忘记在您的后端启用 CORS!
推荐阅读
- python - How can you partition every value of a dictionary and change that value to the first output?
- python - Flask - Firebase 存储 - 图片上传
- javascript - 使用异步 node.js 进行 Twitter API 光标导航
- html - 如何使用动画使文本居中?
- java - Java.io.InputStream 类是表示字节输入流的所有类的超类。它如何读取带有字符的文件?
- node.js - 错误:找不到模块 'rxjs' - 创建 React 应用程序
- pytorch - Conv2d 与 ConvTranspose2d 的步幅
- javascript - 如何更改谷歌地图中的默认标记
- python - Quad函数在python中返回不同的值
- jquery - 读取多文件输入类型会破坏它