Search code examples
node.jsmongodbpassport.jsgoogle-authentication

MongoDB user schema design auth using (local, google, facebook


I want my user to login using local, google or facebook and I would like to know how to structure my user schema in order to enable google and facebook auth, and later save data(like email, name, etc) that is return from facebook/ google. here is my schema table:

const bcrypt = require('bcryptjs')

const userSchema = mongoose.Schema({
    name:{
        type: String,
        required : true
    },
    email:{
        type: String,
        required : true,
        unique: true,
    },
    password:{
        type: String,
        required : true,
    },
    isAdmin:{
        type: Boolean,
        required : true,
        default: false
    },
    isInfluencer:{
        type: Boolean,
        required : true,
        default: false
    },
}, {
    timestamps: true
})

userSchema.methods.matchPassword = async function (enteredPassword) {
    return await bcrypt.compare(enteredPassword, this.password)
  }

userSchema.pre('save', async function (next) {
    if (!this.isModified('password')) {
      next()
    }
  
    const salt = await bcrypt.genSalt(10)
    this.password = await bcrypt.hash(this.password, salt)
    
})

const user = mongoose.model('User', userSchema)

module.exports = user ``` 

It's my first time to implement multiple auth options and haven't found good docs on the net. Any help will be appreciated. Thanks in advance!!!

Solution

  • There is no "magic" solution, you will have to incorporate the logic into your app, I recommend you save 3 (4) different fields email x password, google id and facebook id. based on the authentication method the user choses you will fetch and save the correct field.

    Things to consider.

    password:{
            type: String,
            required : true,
        },
    

    Should not be required as it's not required for google/facebook auth.

    email:{
            type: String,
            required : true,
            unique: true,
        },
    

    Should have a sparse: true field otherwise null values will count torwards the index and you will get errors for all the email-less users from the google auth / facebook auth (unless you are planning to save their email as well and if that's the case you need to add more logic to your login to handle "merges" of users who signed up with email and then X time after sign up with faceook that's associated to the same email.)