【问题标题】:Mongoose Populate users is returning a 404 (forbidden)Mongoose Populate 用户返回 404(禁止)
【发布时间】:2015-06-18 18:46:07
【问题描述】:

我正在尝试在项目中填充用户数组,但我得到了GET http://localhost:9000/api/users 403 (Forbidden)(如果已登录)和GET http://localhost:9000/api/users 403 (Unauthorised)(如果未登录)。所以我相当有信心我的问题是因为用户附加了身份验证,并且当我调用列表项目函数时。

我想要做的只是为每个项目获取一组用户,然后使用 objectid 使用用户名和 profile_image 填充该列表。

这是我所拥有的:

exports.index = function (req, res) {
  Project
    .find(function (err, projects) {
      if (err) { //handle error
        return handleError(res, err);
      }
      return projects;
    }) 
    .populate('users')
    .exec(function (err, projects) { 
      if (err) { //handle error
        return handleError(res, err);
      }
      return res.json(200, projects); 
    });
};

项目架构:

'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var ProjectSchema = new Schema({
  name: String,
  type: String,
  users: [{ type: Schema.Types.ObjectId, ref: 'User' }]
});

ProjectSchema.statics = {   
  load: function (id, cb) {
    this.findOne({ _id : id })
      .populate('users', 'name profile_image')
      .exec(cb);
  }
}
module.exports = mongoose.model('Project', ProjectSchema);

用户架构:

'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crypto = require('crypto');
var authTypes = ['github', 'twitter', 'facebook', 'google'];

var UserSchema = new Schema({
  name: String,
  email: { type: String, lowercase: true },
    profile_image: String,
  role: {
    type: String,
    default: 'user'
  },
  hashedPassword: String,
  provider: String,
  salt: String,
  facebook: {},
  twitter: {},
  google: {},
  github: {}
});

/**
 * Virtuals
 */
UserSchema
  .virtual('password')
  .set(function(password) {
    this._password = password;
    this.salt = this.makeSalt();
    this.hashedPassword = this.encryptPassword(password);
  })
  .get(function() {
    return this._password;
  });

// Public profile information
UserSchema
  .virtual('profile')
  .get(function() {
    return {
      'name': this.name,
      'role': this.role
    };
  });

// Non-sensitive info we'll be putting in the token
UserSchema
  .virtual('token')
  .get(function() {
    return {
      '_id': this._id,
      'role': this.role
    };
  });

/**
 * Validations
 */

// Validate empty email
UserSchema
  .path('email')
  .validate(function(email) {
    if (authTypes.indexOf(this.provider) !== -1) return true;
    return email.length;
  }, 'Email cannot be blank');

// Validate empty password
UserSchema
  .path('hashedPassword')
  .validate(function(hashedPassword) {
    if (authTypes.indexOf(this.provider) !== -1) return true;
    return hashedPassword.length;
  }, 'Password cannot be blank');

// Validate email is not taken
UserSchema
  .path('email')
  .validate(function(value, respond) {
    var self = this;
    this.constructor.findOne({email: value}, function(err, user) {
      if(err) throw err;
      if(user) {
        if(self.id === user.id) return respond(true);
        return respond(false);
      }
      respond(true);
    });
}, 'The specified email address is already in use.');

var validatePresenceOf = function(value) {
  return value && value.length;
};

/**
 * Pre-save hook
 */
UserSchema
  .pre('save', function(next) {
    if (!this.isNew) return next();

    if (!validatePresenceOf(this.hashedPassword) && authTypes.indexOf(this.provider) === -1)
      next(new Error('Invalid password'));
    else
      next();
  });

/**
 * Methods
 */
UserSchema.methods = {
  /**
   * Authenticate - check if the passwords are the same
   *
   * @param {String} plainText
   * @return {Boolean}
   * @api public
   */
  authenticate: function(plainText) {
    return this.encryptPassword(plainText) === this.hashedPassword;
  },

  /**
   * Make salt
   *
   * @return {String}
   * @api public
   */
  makeSalt: function() {
    return crypto.randomBytes(16).toString('base64');
  },

  /**
   * Encrypt password
   *
   * @param {String} password
   * @return {String}
   * @api public
   */
  encryptPassword: function(password) {
    if (!password || !this.salt) return '';
    var salt = new Buffer(this.salt, 'base64');
    return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
  }
};

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

【问题讨论】:

    标签: node.js mongodb mongoose mean-stack angular-fullstack


    【解决方案1】:

    我找到了解决方案,我需要为不需要身份验证的公共用户创建一条新路由:

    router.get('/public', controller.public);
    

    然后我将它添加到控制器:

    /**
     * Get public list of users
     */
    exports.public = function(req, res) {
      User.find({}, 'name profileImage',function (err, users) {
        if(err) return res.send(500, err);
        res.json(200, users);
      });
    };
    

    然后在我的状态提供者中,我将用户解析为使用 /users/public:

    resolve: {
      users: function(usersModel) {
        return usersModel.one('public').getList()
      }
    }
    

    现在已经解决了 403 错误!

    【讨论】:

      猜你喜欢
      • 2013-11-23
      • 2013-12-17
      • 2015-08-16
      • 2020-08-24
      • 1970-01-01
      • 2018-04-14
      • 2013-05-22
      • 2021-09-16
      相关资源
      最近更新 更多