【问题标题】:Logout functionality for React and Express app using JSON Web Tokens使用 JSON Web 令牌的 React 和 Express 应用程序的注销功能
【发布时间】:2021-01-31 08:38:24
【问题描述】:

我只是想使用 Express (node.js) 创建一个注销功能。登录和会话检查器功能运行良好,但我似乎无法删除用户的令牌并在单击注销时结束会话。注意:我是在 Mongodb 中存储数据

api 路由 api/secret 本质上是仪表板。当用户点击它时,他们会收到一条消息“Hello + req.email”没有被删除。

我将如何创建功能以完全退出会话?

服务器.js


const express = require("express");
const logger = require("morgan");
const mongoose = require("mongoose");
const routes = require("./routes");
const session = require('express-session')
// const cookieParser = require("cookie-parser");
const bodyParser = require('body-parser')
const morgan = require('morgan')
const User = require('./models/User')
const secret = 'mysecretsshhh';
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const withAuth = require('./middleware');



const PORT = process.env.PORT || 3001;
// Initialize Express
const app = express();

// create application/json parser
const jsonParser = bodyParser.json()
 
// initialize body-parser to parse incoming parameters requests to req.body
app.use(bodyParser.urlencoded({ extended: true }));

// set morgan to log info about our requests for development use.
app.use(morgan("dev"));

// initialize cookie-parser to allow us access the cookies stored in the browser.
app.use(cookieParser());

// Configure middleware

// Use morgan logger for logging requests
app.use(logger("dev"));
// Parse request body as JSON
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
  app.use(express.static("client/build"));
}
// // Make public a static folder
// app.use(express.static("public"));

// initialize express-session to allow us track the logged-in user across sessions.
app.use(
  session({
    key: "user_sid",
    secret: "somerandomstuffs",
    resave: false,
    saveUninitialized: false,
    cookie: {
      expires: 600000,
    },
  })
);

// This middleware will check if user's cookie is still saved in browser and user is not set, then automatically log the user out.
// This usually happens when you stop your express server after login, your cookie still remains saved in the browser.
app.use((req, res, next) => {
  if (req.cookies.user_sid && !req.session.user) {
    res.clearCookie("user_sid");
  }
  next();
});

app.get('/api/home2', function(req, res) {
  res.send('Welcome!');
});
app.get('/api/secret', withAuth, function(req, res) {
  res.send('Hello ' + req.email);

});

// a simple route that will return a 200 HTTP status if our requester has a valid token:
app.get('/checkToken', withAuth, function(req, res) {
  res.sendStatus(200);
})

// POST route to register a user
app.post('/api/register', function(req, res) {
  const { email, password } = req.body;
  const user = new User({ email, password });
  user.save(function(err) {
    if (err) {
      res.status(500)
        .send("Error registering new user please try again.");
    } else {
      res.status(200).send("Welcome to the club!");
    }
  });
});

//authenticate checker
app.post('/api/authenticate', function(req, res) {
  const { email, password } = req.body;
  User.findOne({ email }, function(err, user) {
    if (err) {
      console.error(err);
      res.status(500)
        .json({
        error: 'Internal error please try again'
      });
    } else if (!user) {
      res.status(401)
        .json({
          error: 'Incorrect email or password'
        });
    } else {
      user.isCorrectPassword(password, function(err, same) {
        if (err) {
          res.status(500)
            .json({
              error: 'Internal error please try again'
          });
        } else if (!same) {
          res.status(401)
            .json({
              error: 'Incorrect email or password'
          });
        } else {
          // Issue token
          const payload = { email };
          const token = jwt.sign(payload, secret, {
            expiresIn: '1h'
          });
          res.cookie('token', token, { httpOnly: true })
            .sendStatus(200);
        }
      });
    }
  });
});

//logout user
app.get('/api/logout',withAuth,function(req,res){

res.clearCookie()
req.session.destroy();
res.sendStatus(200);
}); 

// adding the middleware to our express setup so express can parse cookies passed by our browser
app.use(cookieParser());


app.use(routes);


mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/populatedb");





// Start the server
app.listen(PORT, function () {
  console.log(`????  ==> API Server now listening on PORT ${PORT}!`);
});

middleware.js


const jwt = require('jsonwebtoken');
const secret = 'mysecretsshhh';
const withAuth = function(req, res, next) {
  const token = req.cookies.token;
  if (!token) {
    res.status(401).send('Unauthorized: No token provided');
  } else {
    jwt.verify(token, secret, function(err, decoded) {
      if (err) {
        res.status(401).send('Unauthorized: Invalid token');
      } else {
        req.email = decoded.email;
        console.log("Hi " + req.email )
        next();
      }
    });
  }
}
module.exports = withAuth;

User.js(模型)

const mongoose = require("mongoose");
const bcrypt = require('bcrypt')

var Schema = mongoose.Schema;

var UserSchema = new Schema({
  email: {
    type: String,
    unique: true,
    required: true

  },

  // username: {
  //   type: String,
  //   unique: true,
  //   required: true

  // },
  password: {
    type: String,

    required: true
    // trim: true,
    // required: "Password is Required",
    // validate: [
    //   function(input) {
    //     return input.length >= 6;
    //   },
    //   "Password should be longer."
    // ]
  },

});

UserSchema.pre("save", function (next) {
   // Check if document is new or a new password has been set
  if (!this.isModified("password")) {
    
       // Saving reference to this because of changing scopes
    return next()
  }
  this.password = bcrypt.hashSync(this.password, 10)
  next()
})

//compare password
// UserSchema.methods.comparePassword = function (plainText, callback) {
//   return callback(null, bcrypt.compareSync(plainText, this.password))
// }

UserSchema.methods.isCorrectPassword = function(password, callback){
  bcrypt.compare(password, this.password, function(err, same) {
    if (err) {
      callback(err);
    } else {
      callback(err, same);
    }
  });
}


const userModel = mongoose.model("user", UserSchema)

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

module.exports = userModel

【问题讨论】:

    标签: node.js reactjs mongodb express authentication


    【解决方案1】:

    您缺少 cookie 名称 clearCookie()。 参考文档https://expressjs.com/en/api.html#res.clearCookie

    【讨论】:

    • 不客气,如果你能投票给我的答案,这对我也有帮助。
    猜你喜欢
    • 2015-03-08
    • 2017-11-09
    • 2023-03-29
    • 2011-08-03
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多