【问题标题】:How to return current user information from MongoDB in a MEVN stack app如何在 MEVN 堆栈应用程序中从 MongoDB 返回当前用户信息
【发布时间】:2020-02-09 08:46:03
【问题描述】:

我正在尝试使用 Vue、Express、Node 和 MongoDB 构建一个基本的登录/注册应用程序。我已成功设置 Express 路由器以启用用户注册和登录,并将基本用户信息存储在 MongoDB 中。我正在尝试在登录后将用户数据返回到屏幕。到目前为止,我已经在 Express 中设置了router.get() 以将所有用户的用户名返回到屏幕。但是,我想在 Vue.js 中配置 axios.get() 方法以仅返回登录用户的用户名,而不是存储在 MongoDB 中的所有用户名。通常在 Firebase 中,我会使用 let snapshot = await ref.where('userid', '==', firebase.auth().currentUser.uid).get() 之类的东西专门发回有关当前用户的信息。如何设置我的 axios.get() 方法来执行类似的操作?我的代码如下:

登录页面

<template>
  <b-row>
    <b-col cols="12">
      <h2>
        You are now logged in!
        <b-link @click="logout()">(Logout)</b-link>
      </h2>
      <table style="width:100%">
        <tr>
          <th>User Names</th>
        </tr>
        <tr v-for="user in users" :key="user._id">
          <td>{{ user.username }}</td>
        </tr>
      </table>
      <ul v-if="errors && errors.length">
        <li v-for="error of errors" :key="error._id">
          <b-alert show>{{error.message}}</b-alert>
        </li>
      </ul>
    </b-col>
  </b-row>
</template>

<script>

import axios from 'axios'

export default {
  name: 'BookList',
  data () {
    return {
      users: [],
      errors: []
    }
  },
  created () {
    axios.defaults.headers.common['Authorization'] = localStorage.getItem('jwtToken')
    axios.get(`http://localhost:3000/api/auth`)
      .then(response => {
        this.users = response.data
      })
    },
    methods: {
      logout () {
        localStorage.removeItem('jwtToken')
        this.$router.push({
          name: 'Login'
        })
      }
    }
  }
  </script>

在 Express 中获取路线

router.get('/', function(req, res) {
  User.find(function (err, products) {
    if (err) return next(err);
    res.json(products);
  });
});

用户.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcryptjs');

var UserSchema = new Schema({
  username: {
        type: String,
        unique: true,
        required: true
    },
  password: {
        type: String,
        required: true
    }
});

UserSchema.pre('save', function (next) {
    var user = this;
    if (this.isModified('password') || this.isNew) {
        bcrypt.genSalt(10, function (err, salt) {
            if (err) {
                return next(err);
            }
            bcrypt.hash(user.password, salt, null, function (err, hash) {
                if (err) {
                    return next(err);
                }
                user.password = hash;
                next();
            });
        });
    } else {
        return next();
    }
});

UserSchema.methods.comparePassword = function (passw, cb) {
    bcrypt.compare(passw, this.password, function (err, isMatch) {
        if (err) {
            return cb(err);
        }
        cb(null, isMatch);
    });
};

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

注册路线

router.post('/register', function(req, res) {
  if (!req.body.username || !req.body.password) {
    res.json({success: false, msg: 'Please pass username and password.'});
  } else {
    var newUser = new User({
      username: req.body.username,
      password: req.body.password
    });
    // save the user
    newUser.save(function(err) {
      if (err) {
        return res.json({success: false, msg: 'Username already exists.'});
      }
      res.json({success: true, msg: 'Successful created new user.'});
    });
  }
});

【问题讨论】:

  • @SuleymanSah,你为什么删除你的答案?
  • 你的问题是get route吗?
  • 我认为问题出在 Vue.js 模板中的路由和 axios.get() 方法上。我正在以特定用户身份登录,并希望配置路由和 get 方法以仅将我的用户名返回到屏幕。
  • 我没有使用vue的经验,但我可以在快递方面提供帮助,我取消删除了答案,检查它是否有帮助
  • 路线是否与我的答案中的代码一起使用?

标签: javascript node.js mongodb express vue.js


【解决方案1】:

我假设您的用户模型具有用户名和密码字段,并且您的密码在 db 中加密。

对于使用用户名查找用户,如果用户发现将 user.password 与请求正文中的加密密码进行比较。 如果找不到用户,或者密码不匹配,我发送400-Bad Request

const bcrypt = require("bcryptjs");

router.post("/", async (req, res) => {
  const { username, password } = req.body;

  if (!(username && password))
    return res.status(400).json({ error: "username and password are required" });

  try {
    let user = await User.findOne({ username });
    if (!user) return res.status(400).json({ error: "invalid login" });

    const validPassword = await bcrypt.compare(password, user.password);
    if (!validPassword) return res.status(400).json({ error: "invalid login" });

    user.password = undefined;

    res.json(user);
  } catch (err) {
    console.log(err);
    return next(err);
  }
});

要在保存用户之前对密码进行哈希处理,可以将此代码添加到用户模型中吗?

UserSchema.pre('save', async function (next) {
    this.password = await bcrypt.hash(this.password, 12);
    next();
});

注册路线:

router.post("/register", async (req, res) => {
  const { username, password } = req.body;

  if (!username || !password)
    return res.json({ success: false, msg: "Please pass username and password." });

  try {
    let user = await User.findOne({ username });

    if (user) return res.json({ success: false, msg: "Username already exists." });

    user = new User({ username, password });

    await user.save();

    res.json({ success: true, msg: "Successful created new user." });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went bad" });
  }
});

【讨论】:

  • 再次感谢。这似乎是一个合乎逻辑的答案,但它仍然没有返回特定用户。我在创建的生命周期挂钩中使用了 console.log,但没有数据返回给 this.users。我认为 Vue.js 功能很好。是否有其他可用的 get 路由配置?
  • @JS_is_awesome18 这个路由必须返回用户,如果用户模型有用户名和密码字段,并且密码没有在数据库中保持加密。可以试试邮递员的路线吗?
  • 好电话。我刚刚尝试在邮递员中运行 get 路线。它返回第二个错误,“需要用户名和密码”
  • @实际上这一定是一个帖子请求,我编辑答案
  • 我要注意,密码是用bcrypt-nodejs加密的。
猜你喜欢
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
  • 2012-07-17
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多