Skip to content

Latest commit

 

History

History
149 lines (136 loc) · 4.83 KB

readme.md

File metadata and controls

149 lines (136 loc) · 4.83 KB

User and video model with hooks and JWT

  • plugins in video model ; for aggregation ; for DB call and production level API
  • bcrypt

Let's start

  • in models folder , make two files

    • video.model.js
    • user.model.js
  • check model diagram link

    • user and video model are coupled
      • id is generated by MONGO
      • files are stored in third party like AWS ; so string url
      • in user model , field watchHistory has an array type , as a video is watched , its id is pushed into the array , we can track history
      • in videos model , owner is dependent on user model
  • write schema of user corresponding to its model diagram

    • code snippets
      • index:true : searchable optimization in DB , not to be done for many fields otherwise performance issues
      • password: always encoded before storing in DB
      • import mongoose , {Schema} from "mongoose"; : importing like this , we can write like this const userSchema = new Schema({
username:{
        type:String ,
        ...
        index:true 
    } ,
  • write schema of video corresponding to its model diagram
    • code snippets
      • we will get durataion from the third party service once uploaded the video
duration:{
        type:Number ,
        required: true,
    },
  • True Power of MongoDB
    • Aggregation Pipelining
    • install package by npm install mongoose-paginate-v2
    • in video.model.js ; it is injected as a plugin
import mongoose  , {Schema} from "mongoose";
import mongooseAggregatePaginate from "mongoose-aggregate-paginate-v2"
const videoSchema = new Schema({...
} ,{timestamps:true})
videoSchema.plugin(mongooseAggregatePaginate)
export const Video = mongoose.model("Video" , videoSchema)
  • More Packages : bcrypt and jwt

both are based on cryptography algorithm; to understand go to website jwt.io

  • Three parts:-
    • headers: automatically injected like which algo is used
    • payload: fancy name for data eg id , email
    • verify signature :
      • secret is the power
  • install by npm i bcrypt jsonwebtoken
    • bcrypt vs bcryptjs
      • Almost same
      • helps to hash/encrypt your password
    • jwt :jsonwebtoken
  • how to use concept of pre and post hooks in middleware
  1. pre : just before storing the data , perform this
  2. post: just after storing the data , perform this
  • in user.models.js file append code
    • use classical function declaration
    • next should be there , flag to be passed to next hash(this.password , 10) : 10 means the number of routes to be followed in the algo
    • if(!this.isModified("password")) return next() have to include this to ensure password is encrypted only when created for first time or updated
userSchema.pre("save" , async function(next){
    if(!this.isModified("password")) return next()
    this.password = bcrypt.hash(this.password , 10)
    next()
})
  • Issue Here , again in user.models.js We encrypted the password but the user still have decrypted one
    • so we have to write a custom method to deal with this situation
  • we use the compare() function of bcrypt
userSchema.methods.isPasswordCorrect = async function(password){
    return await bcrypt.compare(password , this.password)
}
  • All about jwt It gives you a token
    • Working : docs
    • some codes
jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' }, function(err, token) {
  console.log(token);
});

using easier syntax

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: '1h' });
  • Here , we do
    • we are using session and cookies both
      • access tokens will not be stored in DB , whereas Refresh tokens will be stored in DB
    • in .env we append ; write any long string , more long , more strong in secret variable
    • expiry :1d means 1 day
    • refresh token : put anything
      • its expiry , longer than access token
ACCESS_TOKEN_SECRET = hiuhrtwoebreoger94_ohohornoh-j4h34i34btgouuhgereoeheogere
ACCESS_TOKEN_EXPIRY = 1d
REFRESH_TOKEN_SECRET = OTNHhoegeohosnofoswbs-hgehgneoit439n5toihfvddsd
REFRESH_TOKEN_EXPIRY = 10d
  • Add one more method To generate access token ; refresh token has less data
userSchema.methods.generateAccessToken = function(){
    return jwt.sign(
        {
            _id:this._id,
            email:this.email,
            username:this.username,
            fullName:this.fullName
        },
        process.env.ACCESS_TOKEN_SECRET,
        {expiresIn:process.env.ACCESS_TOKEN_EXPIRY}
    )
}
userSchema.methods.generateRefreshToken = function(){
    return jwt.sign(
        {
            _id:this._id,
        },
        process.env.REFRESH_TOKEN_SECRET,
        {expiresIn:process.env.REFRESH_TOKEN_EXPIRY}
    )
}