JWT使用签名烹饪来从前端访问JWT令牌

发布于 2025-01-21 22:31:46 字数 2546 浏览 1 评论 0原文

我(我的一生)试图使用JWT令牌创建登录名。我已经为此工作了几天,并且非常困难。

这是我到目前为止的地方。

登录请求|确认用户名和密码正确,创建JSON Web令牌并将其附加到仅HTTP签名的Cookie。然后,使用数据通过JSON发送到前端。我可以从前端的JSON响应中成功访问用户数据。

const loginUser = async (req, res, next) => {
    try {
        const {username, password} = req.body
        //grabbing user associated with our username
        const user = await User.findOne({username:username}) 
        //check if username and password come from the same user
        if (user && (await bcrypt.compare(password, user.password))){
            const token = generateToken(user._id) //creating a jwt token
            //creating a cookie with our token in it
            res.cookie('token', token, {
                maxAge: 1000*60*15,
                httpOnly: true,
                signed: true
            })
            console.log(req.signedCookies)
            //sending our user info to frontend via json
            res.status(200).json({
                _id: user._id,
                name: user.username,
                email: user.email,
            })
        } else {
            res.status(400)
            throw new Error('Invalid credentials')
        }
    } catch (error) {
        next(error)
    }
}

前端登录|登录表单有效,我成功地获得了JSON数据,这没问题。如果需要,我也可以将令牌附加到JSON数据上,我知道如何做到这一点。

<h1>Login</h1>
<form id="login_form">
    <label for="username">Username</label>
    <input type="text" name="username">
    <label for="password">Password</label>
    <input type="password" for="password" name="password">
    <button type="button" onclick="loginSubmit()">Submit</button>
</form>

<script>
    const loginSubmit = async () => {
        const loginForm = document.getElementById('login_form') //grabbing the login_form
        const data = new URLSearchParams() // this can take in form data
        //this for loop runs for each input field for the form passed into FormData()
        for (const pair of new FormData(loginForm)){
            data.append(pair[0], pair[1]) //pair[0] is the name of the input, pair[1] is the value
        }
        const response = await fetch('/user/login', {
            method: 'POST',
            body: data //passing the form data into our req.body
        })
    }
</script>

我的问题现在是什么?我已经确认cookie正在按每个请求发送,并且在我的开发人员控制台中。我只是不明白我需要采取的下一步来验证用户在每个请求上验证用户。我想我了解注销功能。我可以在代币值上重写,并使之成为任意字符串。但是我不明白如何从曲奇的前端验证cookie中的信息,也许我只是整体上都不了解这个过程。

任何帮助都是如此出色。谢谢您的宝贵时间!

I am (for the life of me) trying to create a login using JWT tokens. I have been working on this for days and am having a really hard time.

Here is where I am at so far.

Login Request | Confirms the username and password are correct, creates a json web token and attaches it to a http-only signed cookie. The use data is then sent to the frontend via json. I can successfully access the user data from the json response on the front end.

const loginUser = async (req, res, next) => {
    try {
        const {username, password} = req.body
        //grabbing user associated with our username
        const user = await User.findOne({username:username}) 
        //check if username and password come from the same user
        if (user && (await bcrypt.compare(password, user.password))){
            const token = generateToken(user._id) //creating a jwt token
            //creating a cookie with our token in it
            res.cookie('token', token, {
                maxAge: 1000*60*15,
                httpOnly: true,
                signed: true
            })
            console.log(req.signedCookies)
            //sending our user info to frontend via json
            res.status(200).json({
                _id: user._id,
                name: user.username,
                email: user.email,
            })
        } else {
            res.status(400)
            throw new Error('Invalid credentials')
        }
    } catch (error) {
        next(error)
    }
}

Front-end Login | The login form works and I successfully get the json data no problem. I could also attach the token to the json data if needed and I understand how to do that.

<h1>Login</h1>
<form id="login_form">
    <label for="username">Username</label>
    <input type="text" name="username">
    <label for="password">Password</label>
    <input type="password" for="password" name="password">
    <button type="button" onclick="loginSubmit()">Submit</button>
</form>

<script>
    const loginSubmit = async () => {
        const loginForm = document.getElementById('login_form') //grabbing the login_form
        const data = new URLSearchParams() // this can take in form data
        //this for loop runs for each input field for the form passed into FormData()
        for (const pair of new FormData(loginForm)){
            data.append(pair[0], pair[1]) //pair[0] is the name of the input, pair[1] is the value
        }
        const response = await fetch('/user/login', {
            method: 'POST',
            body: data //passing the form data into our req.body
        })
    }
</script>

My question is now what? I have confirmed the cookie is being sent on each request and is in my developer console. I just don't understand the next step I need to take to authenticate the user on each request. I think I understand logout functionality. I could just rewrite over the token value and make it an arbitrary string. But I do not understand how to verify the information in the cookie from the front end of maybe I just do not understand the process as a whole.

Any help would be so wonderful. Thank you for your time!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最初的梦 2025-01-28 22:31:47

使用JWT代币的一种常见方法是通过创建一个身份验证中间件来验证每个用户请求,该验证中间件每次将请求发送到受保护的路由时都会验证令牌。

例如

var cookieParser = require('cookie-parser');

app.use(cookieParser());

const auth = async (req, res, next) => {
  try {
    token = req.signedCookies.token;
    if (token) {
      res.locals.decodedData = jwt.verify(token, JWT_SECRET);
      next();
    } else {
        res.status(401).json({message: 'not logged in'});
    }
  } catch (error) {
    // jwt.verify() throws an error if the token is invalid
    res.status(401).json({message: 'invalid token'});
    console.log(error);
  }
};

app.get('/super/secret/files', auth, givefiles); 

,仅一旦已验证令牌,就只会调用Next()函数,这意味着/super/Secret/necret/files路由中使用的给予文件函数永远不会用于未经验证的用户。

您还可以通过这样做的特定路线下的每条路线进行操作:

app.use('/secret', auth);
app.get('/secret/file1', giveFile1);
app.get('/secret/file2', giveFile2);

这将自动将验证中间件应用于/secret路由下的所有路径。

A common way to use JWT tokens is to verify each user request by creating an authentication middleware that verifies the token each time a request is sent to a protected route.

For example

var cookieParser = require('cookie-parser');

app.use(cookieParser());

const auth = async (req, res, next) => {
  try {
    token = req.signedCookies.token;
    if (token) {
      res.locals.decodedData = jwt.verify(token, JWT_SECRET);
      next();
    } else {
        res.status(401).json({message: 'not logged in'});
    }
  } catch (error) {
    // jwt.verify() throws an error if the token is invalid
    res.status(401).json({message: 'invalid token'});
    console.log(error);
  }
};

app.get('/super/secret/files', auth, givefiles); 

Here the next() function is only called once the token has been verified meaning the giveFiles function used in the /super/secret/files route will never be run for an unauthenticated user.

You can also make every route under a certain route protected by doing this:

app.use('/secret', auth);
app.get('/secret/file1', giveFile1);
app.get('/secret/file2', giveFile2);

This automatically applies the auth middleware to all paths under the /secret route.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文