Hi I have just started to get into learning Node.js and trying to build a REST API. By my understanding to return a jwt token for user login its good practice to also combine the use of csrf tokens, as well as in any other form data.
Now i have this code here:
//Packages
const { required } = require("@hapi/joi");
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const csrf = require("csurf");
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
//Middleware
const csrfProtection = csrf({ cookie: true });
const parseForm = bodyParser.urlencoded({ extended: false });
//Models
const UserModel = require("../Models/Users");
//Validaiton Schemas
const UserValidations = require("../Validations/userValidationSchemas");
//Security Functions
const passwords = require("../Security/hashing");
//Handlers
const UserState = require("../Handlers/UserState");
router.get("/", csrfProtection, (req, res) => {
res.send("users");
});
router.get("/userById/:userId", csrfProtection, async (req, res) => {
try {
const user = await UserModel.findOne({ _id: req.params.userId });
res.send(user);
} catch (error) {
return res.status(400).send(error);
}
});
//Create new User
router.post("/newUser", async (req, res) => {
//validate submitted data to match to schema
const { error } = UserValidations.newUserValidationSchema(req.body);
if (error) return res.status(400).send(error.details[0]).message;
//check for existing user with same email
const emailExists = await UserModel.findOne({ email: req.body.email });
if (emailExists) return res.status(400).send("Email already exists");
//hash password
const hashedPassword = await passwords.hashPassword(req.body.password);
if (hashedPassword == null)
return res
.status(400)
.send("Password could not be hashed as invalid format provided");
//If all is good create the new user
const UserData = new UserModel({
title: req.body.title,
name: req.body.name,
surname: req.body.surname,
email: req.body.email,
password: hashedPassword
});
try {
const saveUser = await UserData.save();
res.send(saveUser);
} catch (error) {
res.status(400).send(error);
}
});
//Auth login
router.post("/auth-login", async (req, res) => {
//Validate data before we check it against db
const { error } = UserValidations.authUserLoginValidationSchema(req.body);
if (error) return res.status(400).send(error.details[0]).message;
//check if such user exists
const user = await UserModel.findOne({ email: req.body.email });
if (!user) return res.status(400).send("No such user exists");
const checkPassword = await passwords.comparePassword(
req.body.password,
user.password,
UserState.LogUserIn,
user,
req.body.remember_user
);
});
/*
TODO user update
TODO user logged tokens
*/
module.exports = router;
And how is it that with GET routes csrf tokens are fine but when implemented to POST, it complains with an *Invalid token'?
When i try to test and debug with postman it does the crying? Also is which is best practice to save the jwt token in the headers or the cookie/session?
question from:
https://stackoverflow.com/questions/65946981/implementing-csrf-tokens-in-post-routes-with-node-js 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…