node.js - 使用 Node.js/MongooseJs 在 MongoDb 集合中记录多态性 -

标签 node.js mongodb mongoose

我需要维护一个包含[用户] 文档的“用户”集合,以便为我的站点实现身份验证机制。

[用户] ~ {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/

相关文章:

javascript - 如何在 Mongoose 中迭代单个键中的多个值

node.js - now.js 如何在没有浏览器(简单客户端)的情况下获取 'now' 对象?

node.js - 使用 cli 在现有 Angular 2 应用程序上进行 Angular 通用安装

node.js - 使用 Node JS 连接到 Atlas MongoDB 时出错

node.js - 在 SailsJS 中维护模型更新历史

node.js - 如何修复 "MongoError: database names cannot contain the character '/' "

node.js提示: how to diable the appearance of the word 'prompt' ?

node.js - 为什么 NodeJs 通常使用 MongoDB 而不是 Mysql?

mongodb - 如何使 Mongo 始终在我的 Azure 服务器上自动运行?

node.js - 使用collection.find()无法在mongodb中找到集合的内容