How to return current user information from MongoDB in a MEVN stack app

旧巷老猫 提交于 2020-01-06 06:59:14

问题


I am attempting to build a basic login/registration app using Vue, Express, Node, and MongoDB. I have been successful in setting up the Express router to enable registration and logging in of users, with basic user info stored in MongoDB. I am attempting to return user data back to the screen after logging in. So far, I have set up router.get() in Express to return the username of all users back to the screen. However, I want to configure the axios.get() method in Vue.js to return only the username of the logged in user, as opposed to all the user names stored in MongoDB. Normally in Firebase I would use something like let snapshot = await ref.where('userid', '==', firebase.auth().currentUser.uid).get() to send back info exclusively about the current user. How can I set up my axios.get() method to execute something similar? My code is below:

logged in page

<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>

GET route in Express

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

User.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);

Register route

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.'});
    });
  }
});

回答1:


I assume your user model has username and password fields, and your password is encrypted in db.

For finding user with username, if user found comparing the user.password with the encrypted password in the request body. If user not found, or passwords not match, I send 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);
    }

});

To hash the password before saving the user, can you add this code to the user model?

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

Register route:

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' });
    }

});


来源:https://stackoverflow.com/questions/58347756/how-to-return-current-user-information-from-mongodb-in-a-mevn-stack-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!