Sequelize:不要return密码
Sequelize: don't return password
我正在使用 Sequelize 为用户记录进行数据库查找,我希望模型的默认行为为 not return password
该记录的字段。 password
字段是一个散列,但我仍然不想 return 它。
我有几个可行的选项,但 none 似乎特别好:
为 User
模型创建自定义 class 方法 findWithoutPassword
并在该方法中使用 attributes
执行 User.find
设置如图Sequelize docs
做一个正常的User.find
并在控制器中过滤结果(不是首选)
使用其他库去除不需要的属性
有没有更好的方法?最好的是,如果有一种方法可以在 Sequelize 模型定义中指定从不 return password
字段,但我还没有找到一种方法来做到这一点。
我建议覆盖 toJSON
函数:
sequelize.define('user', attributes, {
instanceMethods: {
toJSON: function () {
var values = Object.assign({}, this.get());
delete values.password;
return values;
}
}
});
或者在 sequelize v4
const User = sequelize.define('user', attributes, {});
User.prototype.toJSON = function () {
var values = Object.assign({}, this.get());
delete values.password;
return values;
}
toJSON
在数据返回给用户时被调用,因此最终用户不会看到密码字段,但它在您的代码中仍然可用。
Object.assign
克隆返回的对象 - 否则您将从实例中完全删除 属性。
scoping attributes as discussed here有一个插件。
我使用了已接受答案中提到的覆盖,除了我调用原始 toJSON
而不是 get
和 this.constructor.super_.prototype.toJSON.apply(this, arguments)
api docs[ 中所述=15=]
也许你可以在 find
时在你的属性中添加 exclude
,如下所示:
var User = sequelize.define('user', attributes);
User.findAll({
attributes: {
exclude: ['password']
}
});
阅读docs了解更多详情
另一种方法是向用户模型添加默认范围。
在模型的选项对象中添加这个
defaultScope: {
attributes: { exclude: ['password'] },
}
或者您可以创建一个单独的范围以仅在某些查询中使用它。
在模型的选项对象中添加这个
scopes: {
withoutPassword: {
attributes: { exclude: ['password'] },
}
}
然后就可以在查询中使用了
User.scope('withoutPassword').findAll();
我喜欢结合使用 Pawan 的两个答案并声明如下:
defaultScope: {
attributes: { exclude: ['password'] },
},
scopes: {
withPassword: {
attributes: { },
}
}
这允许我在默认情况下排除密码并使用 withPassword
范围在需要时显式 return 密码,例如当 运行 登录方法时。
userModel.scope('withPassword').findAll()
这确保在通过引用字段包含用户时不会 return 编辑密码,例如
accountModel.findAll({
include: [{
model: userModel,
as: 'user'
}]
})
下面的代码对我有用。我们希望在运行时访问实例属性,但在将数据发送到客户端之前将其删除。
const Sequelize = require('sequelize')
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname')
const PROTECTED_ATTRIBUTES = ['password', 'token']
const Model = Sequelize.Model
class User extends Model {
toJSON () {
// hide protected fields
let attributes = Object.assign({}, this.get())
for (let a of PROTECTED_ATTRIBUTES) {
delete attributes[a]
}
return attributes
}
}
User.init({
email: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
validate: {
isEmail: true
}
},
password: {
type: Sequelize.STRING,
allowNull: false
},
token: {
type: Sequelize.STRING(16),
unique: true,
allowNull: false
},
},
{
sequelize,
modelName: 'user'
})
module.exports = User
我可以通过在 returns undefined
字段中添加 getter 来实现此功能
firstName: {
type: DataTypes.STRING,
get() {
return undefined;
}
}
当模型包含在另一个模型中时, 不起作用。
我有一个虚拟字段,比如 fullName
,它取决于我想隐藏的字段,比如 firstName
和 lastName
。而基于defaultScope
的在这种情况下不起作用。
您可以通过排除属性以一种简单的方式做到这一点。请参见下面的代码(注释行)
Patient.findByPk(id, {
attributes: {
exclude: ['UserId', 'DiseaseId'] // Removing UserId and DiseaseId from Patient response data
},
include: [
{
model: models.Disease
},
{
model: models.User,
attributes: {
exclude: ['password'] // Removing password from User response data
}
}
]
})
.then(data => {
res.status(200).send(data);
})
.catch(err => {
res.status(500).send({
message: `Error retrieving Patient with id ${id} : ${err}`
});
});
我正在使用 Sequelize 为用户记录进行数据库查找,我希望模型的默认行为为 not return password
该记录的字段。 password
字段是一个散列,但我仍然不想 return 它。
我有几个可行的选项,但 none 似乎特别好:
为
User
模型创建自定义 class 方法findWithoutPassword
并在该方法中使用attributes
执行User.find
设置如图Sequelize docs做一个正常的
User.find
并在控制器中过滤结果(不是首选)使用其他库去除不需要的属性
有没有更好的方法?最好的是,如果有一种方法可以在 Sequelize 模型定义中指定从不 return password
字段,但我还没有找到一种方法来做到这一点。
我建议覆盖 toJSON
函数:
sequelize.define('user', attributes, {
instanceMethods: {
toJSON: function () {
var values = Object.assign({}, this.get());
delete values.password;
return values;
}
}
});
或者在 sequelize v4
const User = sequelize.define('user', attributes, {});
User.prototype.toJSON = function () {
var values = Object.assign({}, this.get());
delete values.password;
return values;
}
toJSON
在数据返回给用户时被调用,因此最终用户不会看到密码字段,但它在您的代码中仍然可用。
Object.assign
克隆返回的对象 - 否则您将从实例中完全删除 属性。
scoping attributes as discussed here有一个插件。
我使用了已接受答案中提到的覆盖,除了我调用原始 toJSON
而不是 get
和 this.constructor.super_.prototype.toJSON.apply(this, arguments)
api docs[ 中所述=15=]
也许你可以在 find
时在你的属性中添加 exclude
,如下所示:
var User = sequelize.define('user', attributes);
User.findAll({
attributes: {
exclude: ['password']
}
});
阅读docs了解更多详情
另一种方法是向用户模型添加默认范围。
在模型的选项对象中添加这个
defaultScope: {
attributes: { exclude: ['password'] },
}
或者您可以创建一个单独的范围以仅在某些查询中使用它。
在模型的选项对象中添加这个
scopes: {
withoutPassword: {
attributes: { exclude: ['password'] },
}
}
然后就可以在查询中使用了
User.scope('withoutPassword').findAll();
我喜欢结合使用 Pawan 的两个答案并声明如下:
defaultScope: {
attributes: { exclude: ['password'] },
},
scopes: {
withPassword: {
attributes: { },
}
}
这允许我在默认情况下排除密码并使用 withPassword
范围在需要时显式 return 密码,例如当 运行 登录方法时。
userModel.scope('withPassword').findAll()
这确保在通过引用字段包含用户时不会 return 编辑密码,例如
accountModel.findAll({
include: [{
model: userModel,
as: 'user'
}]
})
下面的代码对我有用。我们希望在运行时访问实例属性,但在将数据发送到客户端之前将其删除。
const Sequelize = require('sequelize')
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname')
const PROTECTED_ATTRIBUTES = ['password', 'token']
const Model = Sequelize.Model
class User extends Model {
toJSON () {
// hide protected fields
let attributes = Object.assign({}, this.get())
for (let a of PROTECTED_ATTRIBUTES) {
delete attributes[a]
}
return attributes
}
}
User.init({
email: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
validate: {
isEmail: true
}
},
password: {
type: Sequelize.STRING,
allowNull: false
},
token: {
type: Sequelize.STRING(16),
unique: true,
allowNull: false
},
},
{
sequelize,
modelName: 'user'
})
module.exports = User
我可以通过在 returns undefined
firstName: {
type: DataTypes.STRING,
get() {
return undefined;
}
}
当模型包含在另一个模型中时,
我有一个虚拟字段,比如 fullName
,它取决于我想隐藏的字段,比如 firstName
和 lastName
。而基于defaultScope
的
您可以通过排除属性以一种简单的方式做到这一点。请参见下面的代码(注释行)
Patient.findByPk(id, {
attributes: {
exclude: ['UserId', 'DiseaseId'] // Removing UserId and DiseaseId from Patient response data
},
include: [
{
model: models.Disease
},
{
model: models.User,
attributes: {
exclude: ['password'] // Removing password from User response data
}
}
]
})
.then(data => {
res.status(200).send(data);
})
.catch(err => {
res.status(500).send({
message: `Error retrieving Patient with id ${id} : ${err}`
});
});