J
J
JoyRax2021-08-28 19:52:53
Express.js
JoyRax, 2021-08-28 19:52:53

Error: Can't set headers after they are sent. I can't figure out what happened?

Mistake:

Error: Can't set headers after they are sent.
    at SendStream.headersAlreadySent (C:\Users\Dmytro Dryshliuk\Documents\projects\ilerex\node_modules\send\index.js:390:13)
    at SendStream.send (C:\Users\Dmytro Dryshliuk\Documents\projects\ilerex\node_modules\send\index.js:617:10)
    at onstat (C:\Users\Dmytro Dryshliuk\Documents\projects\ilerex\node_modules\send\index.js:729:10)
    at FSReqCallback.oncomplete (node:fs:199:5)


everything worked fine and suddenly all the routes fell and an error began to appear

./server.js

const express = require('express')
const http = require('http')
const cookie = require('cookie-parser')
const config = require('./config')

const app = express()
const server = http.Server(app)

app.use(express.urlencoded({ extended: true }))
app.use(cookie(config.SECRET_COOKIE))
app.use(express.static('public'))
app.use(express.json())

const start = async () => {
  try {
    const Models = {
      User: await require('./models/user.model')(),
      Jwt: await require('./models/jwt.model')()
    }

    require('./routers/auth.router')(app, Models)
    require('./routers/main.router')(app, Models)

    server.listen(config.PORT, () => console.log('server started...'))
  } catch (e) {
    console.log(e)
  }
}

start()


./routers/auth.router.js

const { Router } = require('express')
const auth_controller = require('../controllers/auth.controller')
const auth_middleware = require('../controllers/middlewares/auth.middleware')

module.exports = (app, model = {}) => {
  const router = new Router()
  const Controller = new auth_controller(model)

  router.get('/login', auth_middleware, Controller.login)
  router.get('/signup', auth_middleware, Controller.signup)
  router.get('/logout', auth_middleware, Controller.logout)

  router.post('/api/login', auth_middleware, Controller.login_api)
  router.post('/api/signup', auth_middleware, Controller.signup_api)

  app.use(router)
}


./controllers/auth.controller.js

const jwt = require('jsonwebtoken')
const bcrypt = require('bcryptjs')
const config = require('../config')
const path = require('path')

class auth_controller {
  constructor (Model) {
    this.User = Model.User
    this.Jwt = Model.Jwt
  }
  login = async (req, res) => {
    if (req.isAuth) {
      return res.redirect('/')
    }
    return res.sendFile(path.join(__dirname, '../public/login.html'))
  }
  signup = async (req, res) => {
    if (req.isAuth) {
      return res.redirect('/')
    }
    return res.sendFile(path.join(__dirname, '../public/signup.html'))
  }
  login_api = async (req, res) => {
    if (req.isAuth) {
      return res.redirect('/')
    }

    const { login, password } = req.body

    const user = await this.User.findOne({ login })
    if (!user) {
      console.log('[LOGIN ERROR] - login not found')
      return res.redirect('/login?error=login_not_found')
    }

    if (!bcrypt.compareSync(password, user.password)) {
      console.log('[LOGIN ERROR] - wrong password')
      return res.redirect('/login?error=wrong_password')
    }

    const jwt_access = jwt.sign({ id: user._id }, config.SECRET_ACCESS, {expiresIn: "14m"} )
    const jwt_refresh = jwt.sign({ id: user._id }, config.SECRET_REFRESH, {expiresIn: "30d"} )

    const token = new this.Jwt({ refresh: jwt_refresh })
    await token.save()

    res.cookie('jwt_access', jwt_access)
    res.cookie('jwt_refresh', jwt_refresh)

    return res.redirect('/')
  }
  signup_api = async (req, res) => {
    if (req.isAuth) {
      return res.redirect('/')
    }

    const { login, password } = req.body

    const candidate = await this.User.findOne({ login })
    if (candidate) {
      console.log('[SIGNUP ERROR] - login is busy')
      return res.redirect('/signup?error=login_is_busy')
    }

    const user = new this.User({
      login: login,
      password: bcrypt.hashSync(password, 10)
    })
    await user.save()

    return res.redirect('/login')
  }
  logout = async (req, res) => {
    await this.Jwt.deleteOne({ refresh: req.cookies.jwt_refresh })

    res.cookie('jwt_access', '', { maxAge: -1 })
    res.cookie('jwt_refresh', '', { maxAge: -1 })

    return res.redirect('/login')
  }
}

module.exports = auth_controller


./controllers/middlewares/auth.middleware.js

const jwt = require('jsonwebtoken')
const config = require('../../config')

module.exports = (req, res, next) => {
  if (req.method === "OPTIONS") {
    next()
  }

  try {
    const token = req.cookies.jwt_access
    if (!token) {
      console.log('нету токена')
      req.isAuth = false
      next()
    }
    const decodedData = jwt.verify(token, config.SECRET_ACCESS)
    req.user_id = decodedData.id
    req.isAuth = true
    next()
  } catch (e) {
    req.isAuth = false
    next()
  }
}


./models/user.model.js

const mongoose = require('mongoose')
const config = require('../config')

const User = new mongoose.Schema({
    login: {
    type: String,
    unique: true,
    required: true
  },
    password: {
    type: String,
    required: true
  }
})

module.exports = async () => {
  return await mongoose.createConnection(config.DB_ACCOUNTS).model('User', User)
}


like all the necessary files showed

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
JoyRax, 2021-08-28
@JoyRax

did not expect that you need to return to the middleware
return next()

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question