我有一个简单的任务管理应用程序,客户端是用REACT做的,后端是用NODE JS做的。它有一个简单的登录,从服务器生成一个令牌,作为cookie发送给客户端(使用json web令牌),客户端接收它并将其存储在头部(使用js-cookie)。本地一切正常,问题是当我在不同的域上托管它们时,客户端托管在www.example.com上Netlify.app,服务器托管在Render.com上。当请求用户的身份验证cookie(令牌)时,它失败并返回一个错误,告诉我令牌无效并拒绝我访问:消息:“无效令牌,访问被拒绝”.
import { TOKEN_SECRET } from "../config.js";
import jwt from "jsonwebtoken";
export const authRequired = (req, res, next) => {
const { token } = req.cookies;
if (!token)
return res.status(401).json({ Mensaje: "Token invalido, Acceso denegado" });
jwt.verify(token, TOKEN_SECRET, (err, user) => {
if (err) return res.status(403).json({ mensaje: "token invalido" });
req.user = user;
next();
});
};
我的jwt.js:
import jwt from "jsonwebtoken";
import { TOKEN_SECRET } from "../config.js";
export function createAccessToken(payload) {
return new Promise((res, rej) => {
jwt.sign(payload, TOKEN_SECRET, { expiresIn: "1d" }, (err, token) => {
if (err) rej(err);
res(token);
});
});
}
来自客户:AuthContext.jsx:
import { createContext, useContext, useState, useEffect } from "react";
import Cookies from "js-cookie";
import {
registerRequest,
loginRequest,
verifyTokenRequest,
} from "../api/auth.js";
export const AuthContext = createContext();
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error("El useAuth debe ser usado con un AuthProvider");
}
return context;
};
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [FormErrors, setFormErrors] = useState([]);
const [loading, setLoading] = useState(true);
const signup = async (user) => {
try {
const res = await registerRequest(user);
setUser(res.data);
setIsAuthenticated(true);
} catch (error) {
if (Array.isArray(error.response.data)) {
setFormErrors(error.response.data);
}
setFormErrors(error.response.data);
console.log(error.response.data);
}
};
const signin = async (user) => {
try {
const res = await loginRequest(user);
setUser(res.data);
setIsAuthenticated(true);
} catch (error) {
if (Array.isArray(error.response.data)) {
setFormErrors(error.response.data);
}
setFormErrors(error.response.data);
console.log(error.response.data);
}
};
const logout = () => {
Cookies.remove("token");
setIsAuthenticated(false);
setUser(null);
};
useEffect(() => {
if (FormErrors.length > 0) {
const timer = setTimeout(() => {
setFormErrors([]);
}, 10000);
return () => clearTimeout(timer);
}
}, [FormErrors]);
useEffect(() => {
async function checkLogin() {
const jCookies = Cookies.get();
if (!jCookies.token) {
setIsAuthenticated(false);
setLoading(false);
return setUser(null);
}
try {
const res = await verifyTokenRequest(jCookies.token);
if (!res.data) {
setIsAuthenticated(false);
setLoading(false);
return;
}
setIsAuthenticated(true);
setUser(res.data);
setLoading(false);
} catch (error) {
setIsAuthenticated(false);
setUser(null);
setLoading(false);
}
}
checkLogin();
}, []);
return (
<AuthContext.Provider
value={{
signup,
signin,
logout,
user,
isAuthenticated,
FormErrors,
loading,
}}
>
{children}
</AuthContext.Provider>
);
};
Axios授权人:
import axios from "./axios.js";
export const registerRequest = (user) => axios.post(`/register`, user);
export const loginRequest = (user) => axios.post(`/login`, user);
export const verifyTokenRequest = () => axios.get("/verify");
Axios示例:
import axios from "axios";
const instance = axios.create({
baseURL: "https://exampleurl.com/api"
withCredentials: true,
});
export default instance;
稍微调查一下,我只读到为了避免这个问题,我必须在同一个域上托管服务器和客户端。然而,这只是一个实践项目,我不想花钱在VPS或托管。另一种解决方案是使用代理,但我不知道如何配置代理。我还能做些什么来让客户端将令牌存储为cookie,而不必将服务器或客户端从它们托管的位置移动,或者我必须为此付费吗?
PD:这是我第一个使用Node js和REACT的项目
1条答案
按热度按时间gwbalxhn1#
我不知道如果没有自定义域设置这是可能的-你不能设置一个cookie的域是一个不同的域。例如,myapp.netlify.com无法为mybackend.onrender.com设置Cookie。
如果你不是100%依赖netlify,那么在render上托管你的react应用和你的应用是很容易的(而且是免费的)。这样,您就可以使用Cookie,因为这两个应用程序将位于
onrender.com
的同一个根域中