我需要维护一个包含[用户] 文档的“用户”集合,以便为我的站点实现身份验证机制。
[用户] ~ {color: string, username:string, password-hash:string, password-salt: string}
此外,每个 [User] 可以是 3 种颜色中的一种 - [RedUser]、[BlueUser] 和 [GreenUser ] 并且根据颜色会有不同的架构。所有扩展自 [User] 模式:
[RedUser] ~ Union( [User], {redfield:string} )
[GreenUser] ~ Union( [User], {greenfield:boolean} )
[BlueUser] ~ Union( [User], {bluefield:number} )
例如绿色用户 - {color:'green',username:'bob',password-hash:'1313a...',password-salt:'...'}
对于身份验证,我想使用一般的 [User] 模式查询“用户”集合,因为我只需要知道密码哈希即可。
但是,我想要一个函数如下(伪代码):
Authenticate( username, password )
userDoc <- users.findOne({username:username})
if badPassword(usersDoc.password-hash,password) throw error
else
if userDoc.color=='red'
return recast(userDoc, RedUser)
if userDoc.color=='green'
return recast(userDoc, BlueUser)
if userDoc.color=='blue'
return recast(userDoc, GreenUser)
例如,我如何才能将 [User] 文档向上转换为 [RedUser]?
我正在使用 Node.js/MongooseJs/Coffeescript
谢谢!
最佳答案
真的很简单,我们只是利用 https://github.com/briankircho/mongoose-schema-extend 中的小而有用的 mongoose-schema-extend
包
###
Dependencies.
###
mongoose = require('mongoose')
extend = require('mongoose-schema-extend')
###
Main
###
class Demo
constructor: (dbUrl)->
@db = mongoose.createConnection( dbUrl )
userSchema = new mongoose.Schema
username : { type: String, default: "" }
password_hash : { type: String, default: "" }
,
{collection : 'users', discriminatorKey : 'color'}
userSchema.methods.verifyPassword = (pass)->
console.log("is it a good password? " + (this.password_hash==pass))
redSchema = userSchema.extend
redfield : { type: String, default: "red" }
redSchema.methods.printColor = ->
console.log("RED!")
blueSchema = userSchema.extend
bluefield : { type: String, default: "blue" }
blueSchema.methods.printColor = ->
console.log("BLUE!")
greenSchema = userSchema.extend
greenfield : { type: String, default: "green" }
greenSchema.methods.printColor = ->
console.log("GREEN!")
# create the mongoose db models
@UserModel = @db.model('User', userSchema)
@RedModel = @db.model('Red', redSchema)
@BlueModel = @db.model('Blue', blueSchema)
@GreenModel = @db.model('Green', greenSchema)
populate: ->
user1 = new @RedModel({username:'user1',password_hash:'pass1',redfield:'blabla'})
user1.save()
user2 = new @GreenModel({username:'user2',password_hash:'pass2',greenfield:'blabla2'})
user2.save()
user3 = new @RedModel({username:'user3',password_hash:'pass3',redfield:'blabla3'})
user3.save()
user4 = new @GreenModel({username:'user4',password_hash:'pass1',greenfield:'dflabla'})
user4.save()
user5 = new @BlueModel({username:'user5',password_hash:'pass2',bluefield:'blabla2'})
user5.save()
user6 = new @BlueModel({username:'user6',password_hash:'pass3',bluefield:'blabla3'})
user6.save()
auth:(username,callback)->
@UserModel.findOne({ username: username }, callback)
###
Start the demo
###
demo = new Demo('mongodb://localhost/testpolymorph')
demo.populate()
demo.auth 'user5', (err,userDoc)->
userDoc.verifyPassword("pass")
userDoc.printColor()
demo.auth 'user3', (err,userDoc)->
userDoc.verifyPassword("pass3")
userDoc.printColor()
demo.auth 'user4', (err,userDoc)->
userDoc.verifyPassword("pass3")
userDoc.printColor()
关于node.js - 使用 Node.js/MongooseJs 在 MongoDb 集合中记录多态性 -,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13099396/