MERN 앱용 백엔드

구성


  • Mongo Atlas database
  • Error Handler
  • User Model
  • User Controller
  • User Authorization Middleware
  • User Routes
  • Express Server

  • Mongo Atlas용 데이터베이스 구성



    시작하려면 다음 종속성에 대해 실행npm install:
  • dotenv
  • express
  • express-async-handler
  • mongoose
  • jsonwebtoken
  • brcyptjs

  • 개발 중 파일 변경 시 노드 서버 자동 재시작에 필요한 항목npm install nodemon -D도 포함하면 도움이 될 것입니다.

    다음을 포함할 .env 파일도 생성합니다.
  • NODE_ENV = 개발
  • MONGO_URI = mongo 데이터베이스에 대한 URL
  • 포트 = 5001
  • JWT_SECRET = 비밀 복숭아

  • ./backend/config/db.js



    이 파일에는 mongodb.com을 통해 생성된 Mongo 데이터베이스에 연결하는 방법이 포함되어 로컬에 저장할 필요 없이 원격 데이터베이스 연결이 가능합니다.

    const mongoose = require('mongoose')
    
    const connectDB = async () => {
      try {
        const conn - await mongoose.connect(process.env.MONGO_URI)
    
        // Include confirmation of connecting to Mongo
        console.log(`MongoDB connected ${conn.connection.host}`)
    
      } catch (error) {
        console.log('MongoDB not connected', error)
        process.exit(1)
      }
    }
    
    // Export the module for use in `index.js`
    module.exports = connectDB
    


    오류 처리기 구성



    사용자 지정 오류 처리기가 있으면 디버깅 피드백을 통해 문제가 발생한 위치를 추적하는 데 도움이 됩니다.

    ./백엔드/미들웨어/errorMiddleware.js




    const errorHandler = (err, req, res, next) => {
      const statusCode = res.statusCode ? res.statusCode : 500
    
      // Call error code retrieved from the response
      res.status(statusCode)
    
      res.json({
        message: err.message,
        stack: process.env.NODE_ENV === 'production' ? null : err.stack,
      })
    }
    
    module.exports = { errorHandler }
    


    사용자 모델 구성



    사용자 모델에는 name , emailpassword 가 포함됩니다. 암호는 해시되고 다른 파일에 솔트 처리됩니다.

    ./backend/models/userModel.js




    const mongoose = require('mongoose')
    
    const userSchema = mongoose.Schema(
      {
        name: {
          type: String,
          required: [true , 'Please provide a name'],
        },
        email: {
          type: String,
          required: [true, 'Please provide an email'],
          unique: true,
        },
        password: {
          type: String,
          required: [true, 'Please provide a password'],
        },
      },
      {
        timestamps: true,
      }
    )
    
    // Export the name of the model ('User') and the module itself (userSchema)
    module.exports = mongoose.model('User', userSchema)
    


    사용자 컨트롤러 구성



    컨트롤러는 모든 사용자 작업에 대한 코드를 보유합니다.

    ./backend/controllers/userController.js




    const jwt = require('jswonwebtoken')
    const bcrypt = require('bcryptjs')
    const asyncHandler = require('express-async-handler')
    const User = require('../models/userModel')
    
    const registerUser = asyncHandler(async (req, res) => {
      // Destructure attributes from request
      const { name, email, password } = req.body
    
      // Check for missing information on the form
      if (!name || !email || !password) {
        res.status(400)
        throw new Error('Please fill in all required fields')
      }
    
      const userExists = await User.findOne({ email })
    
      if (userExists) {
        res.status(400)
        throw new Error('User already exists')
        // Optional to redirect to login page
      }
    
      // Hash password
      const salt = await bcrypt.genSalt(24)
      // Take in `password` and use `salt` for hashing algorithm
      const hashedPassword = await bcrypt.hash(password, salt)
    
      const user = await User.create({
        name, email, password: hashedPassword
      })
    
      if (user) {
        res.status(201).json({
          _id: user.id,
          name: user.name,
          email: user.email,
          token: generateToken(user._id),
        })
      } else {
        res.status(400)
        throw new Error('Invalid user data')
      }
    })
    
    const loginUser = asyncHandler(async (req, res) => {
      const { email, password } = req.body
    
      const user = await User.findOne({ email })
    
      if (user && (await bcrypt.compare(password, user.password))) {
        res.json({
          _id: user.id,
          name: user.name,
          email: user.email,
          token: generateToken(user._id),
        })
      } else {
        res.status(400)
        throw new Error('Invalid credentials')
      }
    })
    
    const generateToken = (id) => {
      return jwt.sign({ id }, process.env.JWT_SECRET, {
        expiresIn: '30d',  // Determines when this token will expire and user will need to login again
      })
    }
    
    module.exports = {
      registerUser,
      loginUser
    }
    


    사용자 인증 미들웨어 구성



    사용자 세부 정보, 생성된 자산 또는 설정과 같이 사용자가 소유한 모든 데이터에 액세스하려면 사용자에게 권한이 필요합니다.

    ./백엔드/미들웨어/authMiddleware.js




    const jwt = require('jsonwebtoken')
    const asyncHandler = require('express-async-handler')
    const User = require('../models/userModel')
    
    const protect = asyncHandler(async (req, res, next) => {
      let token
    
      if (
        req.headers.authorization &&
        req.headers.authorization.startsWith('Bearer')
      ) {
        try {
          token = req.headers.authorization.split(' ')[1]
          const decodedToken = jwt.verify(token, process.env.JWT_SECRET)
          req.user = await User.findById(decodedToken.id).select('-password')
    
          next()
        } catch (error) {
          console.log(error)
          res.status(401)
          throw new Error('Not authorized')
        }
      }
    
      if (!token) {
        res.status(401)
        throw new Error('Not authorized, no token')
      }
    })
    
    module.exports = { protect }
    


    사용자 경로 구성



    인증을 유지하기 위해 미들웨어를 활용하는 동안 사용자에 의한 작업에 따라 조치를 취하기 위해 express에서 사용할 경로입니다.

    ./backend/routes/userRoutes.js




    const express = require('express')
    const router = express.Router()
    const { registerUser, loginUser } = require('../controllers/userController')
    const { protect } = require('../middleware/authMiddleware')
    
    // POST route  api/users/
    router.post('/', registerUser)
    
    // POST route  api/users/login
    router.post('/login', loginUser)
    
    module.exports = router
    


    익스프레스 서버 구성



    이것은 express가 정보를 전송하고 사용자 지정 오류 처리를 통해 나머지 백엔드 파일에 대한 액세스를 허용하는 시작 지점입니다.

    ./백엔드/index.js




    const express = require('express')
    const dotenv = require('dotenv').config()
    const connectDB = require('./config/db')
    const { errorhandler } = require('./middleware/errorMiddleware')
    const port = process.env.PORT || 5001
    
    // Connect to Mongo Atlas database
    connectDB()
    
    const app = express()
    
    app.use(express.json())
    app.use(express.urlencoded({ extended: false })
    
    // Use user routes
    app.use('/api/users', require('./routes/userRoutes'))
    
    app.use(errorhandler)
    
    // Port to be used for the server to run on
    app.listen(port, () => console.log(`Server running on port ${port}`))
    


    결론



    이것은 사용자가 다음 사용 사례에 대해 필요에 따라 사용자 정의할 수 있도록 익스프레스 서버를 설정하기 위한 기본 상용구였습니다.

    Back to top

    좋은 웹페이지 즐겨찾기