英文:
Why is token is undefined on client side?
问题
I make an ecommerce site with nextjs and mongoose using a jwt token in a cookie, going client side in the console, the "application" parameter we can see the cookie which is stored with the name OursiteJWT and it has the value the token:
但经过多次测试后,我们注意到当我检索令牌时,它是未定义的
pages/orders.js :
import { useEffect, useState } from "react";
import axios from "axios";
import jwt from "jsonwebtoken";
import cookie from "cookie";
function Orders() {
const [orders, setOrders] = useState([]);
useEffect(() => {
async function fetchOrders() {
try {
// Get the secret from the API
const secretRes = await axios.get("/api/secret");
const secret = secretRes.data.secret;
console.log(secret);
// Get the JWT token from cookies
const cookies = cookie.parse(document.cookie);
const token = cookies.OursiteJWT;
console.log(token);
// If the token is not present, redirect to the login page
if (!token) {
console.log("No token");
return;
}
// Verify the JWT token
const decoded = jwt.verify(token, secret);
const userId = decoded._id;
// Get user orders from the API
const ordersRes = await axios.get(`/api/orders?user_id=${userId}`);
const orders = ordersRes.data;
setOrders(orders);
} catch (error) {
console.error(error);
}
}
fetchOrders();
}, []);
return (
<div>
{orders.map((order) => (
<div key={order._id}>
<h2>Order {order._id}</h2>
<p>User: {order.name}</p>
<p>Address: {order.address}</p>
<p>City: {order.city}</p>
<p>Products:</p>
<ul>
{order.products.map((product) => (
<li key={product._id}>{product.name}</li>
))}
</ul>
</div>
))}
</div>
);
}
export default Orders;
In the console I have "token not found" and the token value is undefined, the secret is correct.
This is how I stored the token:
api/login.js :
import { initMongoose } from "../../lib/mongoose";
import User from '../../models/User';
import { sign } from "jsonwebtoken";
import { serialize } from "cookie";
initMongoose();
const secret = process.env.SECRET;
export default async function handler(req, res) {
const { email, password } = req.body;
const user = await User.findOne({ email, password });
if (!user) {
res.status(401).json({ message: "Unable to find a user" });
return;
} else {
const token = sign(
{
exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, // 30 days
email: email,
_id: user._id,
},
secret
);
const serialised = serialize("OursiteJWT", token, {
httpOnly: true,
secure: process.env.NODE_ENV !== "development",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 30,
path: "/",
});
res.setHeader("Set-Cookie", serialised);
res.status(200).json({ message: "Success!" });
}
}
英文:
I make an ecommerce site with nextjs and mongoose using a jwt token in a cookie, going client side in the console, the "application" parameter we can see the cookie which is stored with the name OursiteJWT and it has the value the token :
But after several tests we notice that when I retrieve the token it is undefined
pages/orders.js :
import { useEffect, useState } from "react";
import axios from "axios";
import jwt from "jsonwebtoken";
import cookie from "cookie";
function Orders() {
const [orders, setOrders] = useState([]);
useEffect(() => {
async function fetchOrders() {
try {
// Récupère le secret depuis l'API
const secretRes = await axios.get("/api/secret");
const secret = secretRes.data.secret;
console.log(secret);
// Récupère le token JWT depuis les cookies
const cookies = cookie.parse(document.cookie);
const token = cookies.OursiteJWT;
console.log(token);
// Si le token n'est pas présent, redirige vers la page de login
if (!token) {
console.log("pas de token")
return;
}
// Vérifie le token JWT
const decoded = jwt.verify(token, secret);
const userId = decoded._id;
// Récupère les commandes de l'utilisateur depuis l'API
const ordersRes = await axios.get(`/api/orders?user_id=${userId}`);
const orders = ordersRes.data;
setOrders(orders);
} catch (error) {
console.error(error);
}
}
fetchOrders();
}, []);
return (
<div>
{orders.map((order) => (
<div key={order._id}>
<h2>Commande {order._id}</h2>
<p>Utilisateur: {order.name}</p>
<p>Adresse: {order.address}</p>
<p>Ville: {order.city}</p>
<p>Produits:</p>
<ul>
{order.products.map((product) => (
<li key={product._id}>{product.name}</li>
))}
</ul>
</div>
))}
</div>
);
}
export default Orders;
In the console I have "token not found" and the token value is undefined, the secret is correct.
This is how I stored the token :
api/login.js :
import {initMongoose} from "../../lib/mongoose";
import User from '../../models/User';
import { sign } from "jsonwebtoken";
import { serialize } from "cookie";
initMongoose()
const secret = process.env.SECRET;
export default async function handler(req,res){
const {email,password}=req.body;
const user = await User.findOne({email,password});
if(!user){
res.status(401).json({message: "Impossible de trouver un utilisateur"});
return;
}
else{
const token = sign(
{
exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, // 30 days
email: email,
_id: user._id,
},
secret
);
const serialised = serialize("OursiteJWT", token, {
httpOnly: true,
secure: process.env.NODE_ENV !== "development",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 30,
path: "/",
});
res.setHeader("Set-Cookie", serialised);
res.status(200).json({message :"Success!"});
}
}
答案1
得分: 1
你无法检索到它的原因是因为你在cookie上设置了httpOnly: true
。
在生成cookie时使用HttpOnly标志有助于减轻客户端脚本访问受保护的cookie的风险(如果浏览器支持它)。
具有HttpOnly属性的cookie对JavaScript的
Document.cookie
API是不可访问的;它只发送到服务器。例如,存在于服务器端会话中的cookie不需要对JavaScript可用,并且应该具有HttpOnly属性。这个预防措施有助于减轻跨站脚本(XSS)攻击的风险。
详见https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies
英文:
The reason you are unable to retrieve it is because you are setting httpOnly: true
on the cookie.
Using the HttpOnly flag when generating a cookie helps mitigate the risk of client side script accessing the protected cookie (if the browser supports it).
> A cookie with the HttpOnly attribute is inaccessible to the JavaScript
> Document.cookie
API; it's only sent to the server. For example,
> cookies that persist in server-side sessions don't need to be
> available to JavaScript and should have the HttpOnly attribute. This
> precaution helps mitigate cross-site scripting (XSS) attacks.
see https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论