代码之家  ›  专栏  ›  技术社区  ›  d4ne

节点TS:JWT令牌签名,用于验证客户端和后端之间的身份验证问题

  •  1
  • d4ne  · 技术社区  · 1 年前

    在服务器端生成JWT令牌并在响应JSON中的注册请求中将其传递回客户端是否安全?

    目前,我正在以以下方式生成JWT:

    import express from "express";
    import jwt from "jsonwebtoken";
    
    const generateToken = (id: any, res: express.Response) => {
        const token = jwt.sign({ id }, process.env.JWT_SECRET as string, {
            expiresIn: "15d",
        });
    
        return token;
    };
    
    export default generateToken;
    

    以下auth.controller正在使用它:

    import express from "express";
    import User from "../models/user.model";
    import bcrypt from "bcrypt";
    import generateToken from "../utils/generateToken";
    
    export const signup = async (req: express.Request, res: express.Response) => {
        try {
            const { username, password, email } = req.body;
    
            // Check if all fields are filled in and been sent
            if (!username || !password || !email) {
                return res
                    .status(400)
                    .json({ message: "Please fill in all fields" });
            }
    
            // Check if the user already exists
            const userCheck = await User.findOne({ username });
    
            if (userCheck) {
                return res.status(400).json({ message: "User already exists" });
            }
    
            // Check if the email already exists
            const emailCheck = await User.findOne({ email });
    
            if (emailCheck) {
                return res.status(400).json({ message: "Email already exists" });
            }
    
            // Hash the password
            const salt = await bcrypt.genSalt(12);
            const hashedPassword = await bcrypt.hash(password, salt);
    
            // Create a new user
            const newUser = new User({
                username,
                password: hashedPassword,
                email,
            });
    
            // Generate and send token
            if (newUser) {
                const token = generateToken(newUser._id, res);
                await newUser.save();
    
                return res.status(201).json({
                    user: newUser,
                    token: token,
                });
            } else {
                return res.status(500).json({ message: "Something went wrong" });
            }
        } catch (error) {
            console.log(`Error in signup controller: ${error}`);
            return res.status(500).json({ message: "Something went wrong" });
        }
    };
    

    如代码所示,我正在生成JWT令牌,并在客户端帖子的响应中从后端将其发送到客户端。

    // Generate and send token
    if (newUser) {
        const token = generateToken(newUser._id, res);
        await newUser.save();
    
        return res.status(201).json({
            user: newUser,
            token: token,
        });
    } else {
        return res.status(500).json({ message: "Something went wrong" });
    }
    

    在客户端中,它将被保存到冗余的本地存储中。

    auth:"{\"session\":{\"signedIn\":true,\"token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2MWE1Y2U5NjAzYWRhNTMzODA2YjVkZSIsImlhdCI6MTcxMzAwMzc1MywiZXhwIjoxNzE0Mjk5NzUzfQ.v23o2WIIz6bYqxpP_wwG5Q3DZgwXtdPX1pMAnGsDKs4\"},\"user\":{\"avatar\":\"https://via.placeholder.com/150\",\"username\":\"test\",\"email\":\"[email protected]\",\"authority\":\"user\"}}"locale:"{\"currentLang\":\"en\"}"_persist:"{\"version\":-1,\"rehydrated\":true}"
    

    问题 这是一种足够安全的方式将其存储在本地存储器中吗?还是需要设置标头的方式?

    3 回复  |  直到 1 年前
        1
  •  2
  •   Tunay ENGİN    1 年前

    在本地存储中存储JWT令牌可能会使您的应用程序面临安全风险,尤其是XSS(跨站点脚本)攻击。如果恶意脚本被注入您的网站,它们可能会访问存储在本地存储中的令牌,从而可能导致未经授权的访问。

    一种更安全的方法是使用仅HTTP的cookie来存储JWT令牌。通过在响应头中将令牌设置为仅HTTP cookie,可以防止客户端脚本访问它,从而降低XSS攻击的风险。此外,您还可以通过设置cookie的“安全”和“SameSite”属性来增强安全性。

    实例

    if (newUser) {
        const token = generateToken(newUser._id);
        await newUser.save();
    
        res.cookie("jwt", token, {
            httpOnly: true,
            secure: true,
            sameSite: "strict"
        });
    
        return res.status(201).json({
            user: newUser
        });
    } else {
        return res.status(500).json({ message: "Something went wrong" });
    }
    

    这种方法确保JWT令牌在客户端和服务器之间安全存储和传输,降低了安全漏洞的风险。但是,在使用cookie进行身份验证时,请记住实施适当的CSRF(跨站点请求伪造)保护,以防止CSRF攻击。

        2
  •  0
  •   Nishanth C 21BPS1160    1 年前

    在大多数网站中,JWT是在服务器端创建的,并发送回客户端。

    有几种方法可以将JWT发送给客户

    1. 将URL中的JWT作为params发送,以防其从后端域重定向到前端域
    2. 将JWT作为HTTP Cookie发送,正如图奈在上述消息中所讨论的那样

    将JWT存储在本地存储中是一种常见的做法。除非你把JWT的秘密暴露给你的用户(你没有这么做),否则在客户端阅读它是非常困难的。您可以使用本地存储,除非您的应用程序具有非常敏感的功能,如银行或股票,在这种情况下,最好使用基于会话的存储。。

        3
  •  0
  •   Jaluson Jobana    1 年前

    饼干会很好吃。它将根据请求发送。