为了账号安全,请及时绑定邮箱和手机立即绑定

使用快递和MongoDB - 如何注销用户?

使用快递和MongoDB - 如何注销用户?

30秒到达战场 2022-09-23 14:57:37

我正在学习使用Expell和Mongo的NodeJS中的身份验证教程 - 代码实验室#1

我得到了一切完美工作,但本教程没有解决如何注销用户。

据我所知,该会话保存在猫鼬地图集上,这是我正在使用的数据库。当我使用Postman登录用户时,我会获得一个令牌。但我不确定如何配置 /logout 路由。

这是我的代码:

///middleware/auth.js

const jwt = require("jsonwebtoken");


module.exports = function (req, res, next) {

  const token = req.header("token");

  if (!token) return res.status(401).json({ message: "Auth Error" });


  try {

    const decoded = jwt.verify(token, "randomString");

    req.user = decoded.user;

    next();

  } catch (e) {

    console.error(e);

    res.status(500).send({ message: "Invalid Token" });

  }

};

///models/User.js

const mongoose = require("mongoose");


const UserSchema = mongoose.Schema({

  username: {

    type: String,

    required: true

  },

  email: {

    type: String,

    required: true

  },

  password: {

    type: String,

    required: true

  },

  createdAt: {

    type: Date,

    default: Date.now()

  }

});


// export model user with UserSchema

module.exports = mongoose.model("user", UserSchema);

所以我的问题是,如何实现/logout路由,以便当用户单击注销按钮并调用该路由时,他们的令牌将被销毁。我只是在问后端部分。我可以使用公理来处理。


查看完整描述

2 回答

?
湖上湖

TA贡献1668条经验 获得超2个赞

据我所知,您没有保存任何会话数据或在任何地方存储令牌 - 这很棒。您只需在对 API 的请求中将令牌追加到标头即可。

因此,您唯一能做的就是可能使 中的令牌过期,然后确保删除客户端上的令牌 - 可能是本地存储,会话存储等 - 您的客户端代码需要终止令牌,因此无法再次包含它。/logout route

附注:

  1. 您不会在任何地方延长令牌生存期,因此即使用户继续在网站上进行交互,令牌过期也不会更新。您需要手动刷新令牌/生成新令牌才能使令牌出现滑动过期。

  2. 我建议您将令牌保存在饼干中。将 Cookie 设置为“唯一”、“安全”,然后指定域。这要安全得多,并且还允许您从API中使cookie过期。如果您包含的任何脚本遭到入侵,它们可以轻松访问所有用户的令牌。

例:

import {serialize} from 'cookie';

import jsend from 'jsend';


...

const token = jwt.sign(

    {

        id: validationResult.value.id // whatever you want to add to the token, here it is the id of a user

    },

    privateKeyBuffer,

    {

        expiresIn: process.env.token_ttl,

        algorithm: 'RS256'

    });


const cookieOptions = {

    httpOnly: true,

    path: '/',

    maxAge: process.env.token_ttl,

    expires: new Date(Date.now() + process.env.token_ttl),

    sameSite: process.env.cookie_samesite, // strict

    domain: process.env.cookie_domain, // your domain

    secure: process.env.cookie_secure // true

};


const tokenCookie = await serialize('token', token, cookieOptions);


res.setHeader('Set-Cookie', [tokenCookie]);


res.setHeader('Content-Type', 'application/json');

res.status(200).json(jsend.success(true));

然后在注销中:


    // grab from req.cookies.token and validate

    const token = await extractToken(req);


    // you can take action if it's invalid, but not really important

    if(!token) {

       ...

    }


    // this is how we expire it - the options here must match the options you created with!

    const cookieOptions = {

        httpOnly: true,

        path: '/',

        maxAge: 0,

        expires: 0,

        sameSite: process.env.cookie_samesite, // strict

        domain: process.env.cookie_domain, // your domain

        secure: process.env.cookie_secure // true

    };


    // set to empty 

    const tokenCookie = await serialize('token', '', cookieOptions);


    res.setHeader('Set-Cookie', [tokenCookie]);

    res.setHeader('Content-Type', 'application/json');

    res.status(200).json(jsend.success(true));


查看完整回答
反对 回复 6天前
?
慕桂英3389331

TA贡献1699条经验 获得超8个赞

由于您已经使用了JWT,后端将始终检查2件事1。正确的令牌 2.如果该特定时间已结束(您应该处理此时间)

对于第二点,如果用户时间超过前端,则可以删除令牌(如果已将令牌存储在localtorage中)。

对于注销,当用户单击注销时,只需从本地存储中删除jwt并重定向到登录或其他页面


查看完整回答
反对 回复 6天前
  • 2 回答
  • 0 关注
  • 11 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信