Saturday, May 29, 2021

Keeping token in header

 Instead of sending token in response body, need to keep in header so we can track between different pages whether user is authenticated or not.

Earlier we created token manually, but we can use database functionality to do it.

Observe the generateAuthToken method created in userSchema.

models/users.js

const Joi = require("joi");
const mongoose = require("mongoose");
const jwt = require("jsonwebtoken");
const config = require("config");

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 50,
    lowercase: true,
  },
  email: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 50,
    unique: true,
    lowercase: true,
  },
  password: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 255,
  },
});

//can't use arrow function syntax as they don't have the this keyword.They use the calling function object reference.
//so class methods should not use arrow functions, they are only for normal functions.
userSchema.methods.generateAuthToken = function () {
  const token = jwt.sign({ _id: this._id }, config.get("jwtPrivateKey"));
  return token;
};

const User = mongoose.model("User"userSchema);

function validateUser(user) {
  const schema = Joi.object({
    name: Joi.string().min(5).max(50).required(),
    email: Joi.string().min(5).max(255).required().email(),
    password: Joi.string().min(5).max(255).required(),
  });
  return schema.validate(user);
}

exports.User = User;
exports.validate = validateUser;

router/auth.js

const { Uservalidate } = require("../models/user");
const mongoose = require("mongoose");
const express = require("express");
const router = express.Router();
const _ = require("lodash");
const { getHashed } = require("../utils/passwordRelated");
const jwt = require("jsonwebtoken");
const Joi = require("Joi");
const bcrypt = require("bcrypt");
const config = require("config");

router.post("/"async (reqres=> {
  const { error } = validateAuth(req.body);
  if (errorreturn res.status(400).send(error.details[0].message);
  let user = await User.findOne({ email: req.body.email });
  if (!userreturn res.status(400).send("User does'nt exist");
  const validPassword = bcrypt.compare(req.body.passworduser.password);
  if (!validPasswordreturn res.status(400).send("Invalid credentials");
  //const token = jwt.sign({_id:user._id},config.get('jwtPrivateKey'))//'jwtprivatekey'
  const token = user.generateAuthToken();
  res.send(token);
});

function validateAuth(req) {
  const schema = Joi.object({
    email: Joi.string().min(5).max(255).required().email(),
    password: Joi.string().min(5).max(50).required(),
  });
  return schema.validate(req);
}

module.exports = router;

router/users.js

const { Uservalidate } = require("../models/user");
const mongoose = require("mongoose");
const express = require("express");
const router = express.Router();
const _ = require("lodash");
const { getHashed } = require("../utils/passwordRelated");

router.post("/"async (reqres=> {
  const { error } = validate(req.body);
  if (errorreturn res.status(400).send(error.details[0].message);
  let user = await User.findOne({ email: req.body.email });
  if (userreturn res.status(400).send("User already exists");
  user = new User({
    name: req.body.name,
    email: req.body.email,
    password: await getHashed(req.body.password),
  });
  await user.save();
  user = _.pick(user, ["name""email"]);

  const token = user.generateAuthToken();
  //res.send(user);
  res
    .header("x-auth-token"token)
    .send(_.pick(user, ["_id""name""email"]));
});

module.exports = router;

No comments:

Post a Comment