REST 노드를 사용하여 간단하고 안전한 API를 구성합니다.js

이번에 우리는 CRUD 작업을 사용하여 안전한 API REST를 만드는 것을 배웠다. 예를 들어 생성, 읽기, 업데이트, 삭제 등이다.
이 개발은 공공과 개인 API를 포함하고 안전을 위해 JWT를 사용하여 인증을 하고 Bcrypt를 사용하여 비밀번호를 산열합니다.데이터베이스 엔진은 MongoDB에서 실행됩니다.

우선 기본 지식을 복습합시다.


RESTAPI, 노드란 무엇입니까?Js, JWT, Bcrypt, MongoDB, Express?


REST API: HTTP 프로토콜을 사용하여 데이터를 가져오고 작업을 수행하는 시스템 간의 인터페이스입니다.이 예에서 가장 중요한 작업인 POST, GET, PUT 및 DELETE를 사용합니다.
노드Js: 이것은 서버 측이 자바스크립트를 기반으로 하는 운행 환경으로 비동기적이고 이벤트를 위한 체계 구조입니다.구글 기반 V8 엔진.
JWT: 이것은 JSON의 개방 기준(RFC-7519을 바탕으로 영패를 만들고 응용 프로그램과 서비스 간에 데이터를 보내서 진실성을 확보하는 데 사용됩니다.
Bcrypt: Blowfish 암호화에 기반한salt 세션을 포함하여 모든 암호와 관련된 산열을 생성합니다. 두 개의 같은 암호가 같은 산열을 생성하는 것을 방지합니다.
MongoDB: 이것은 문서를 대상으로 하는 NosQL 데이터베이스로 BSON 데이터 구조를 저장합니다.
급행 열차.Js: Node를 위한 프레임입니다.Js, 웹 응용 프로그램을 더욱 효율적으로 만드는 데 도움을 줍니다.

우리 어떡하지?

  • 사용자 등록은 표를 통해 필요한 데이터: 이름, 이메일, 비밀번호를 통과한다.
  • 사용자는 이메일과 비밀번호를 사용하여 인증해야 합니다.
  • 보호된 루트를 사용하려면 사용자는 헤더에 영패를 보내야 한다.
  • 시작합시다!!


    우선 프로젝트를 저장하는 디렉터리를 만들고 npm init 명령을 실행해서 프로젝트를 시작합니다

    이 명령을 실행하면 패키지라는 새 파일을 생성합니다.json.이 파일에는 프로젝트 설정이 포함되어 있습니다.
    {
      "name": "simplesecureapirest",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "MIT"
    }
    
    명령을 사용하여 다음 종속성 설치: npm Install
    npm install express mongoose bcryptjs jsonwebtoken morgan
    npm install nodemon -D
    
    의존 항목을 설치한 후 패키지를 삭제합니다.json은 의존항과 devdependency의 목록을 포함합니다. (우리가 nodemon에 지정한 것과 같습니다.)
    "dependencies": {
        "bcryptjs": "^2.4.3",
        "express": "^4.17.1",
        "jsonwebtoken": "^8.5.1",
        "mongoose": "^5.11.8",
        "morgan": "^1.10.0"
      },
      "devDependencies": {
        "nodemon": "^2.0.6"
      }
    }
    

    MVC 모드(모델 뷰 컨트롤러)


    이것은 소프트웨어 체계 구조로 구성 요소를 대상으로 나누는데 하나는 응용 프로그램 데이터에 사용되고 다른 하나는 사용자의 보기와 제어 논리에 사용된다.

    서버 만들기


    우리가 만들기 시작한 디렉터리에 새 파일 서버를 만듭니다.js
    const express = require('express');
    const morgan = require('morgan');
    const pkg = require('./package.json');
    
    
    const app = express();
    
    
    // Settings
    app.set('pkg', pkg);
    
    
    // Middleware
    app.use(morgan('dev'));
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    
    
    // Routes
    
    
    // Welcome Route
    app.get('/', (req, res) => {
        res.json({
            author: app.get('pkg').author,
            name: app.get('pkg').name,
            description: app.get('pkg').description,
            version:app.get('pkg').version
        })
    })
    
    
    app.listen(3000, () => {
        console.log('Server running on port: 3000')
    });
    
    모든 것이 올바른지 확인하려면 다음 명령을 사용하여 서버를 시작합니다.npm run dev
    그런 다음 브라우저http://localhost:3000에서 다음 주소를 액세스하면 다음 질문에 답해야 합니다.
    // 20201224010027
    // http://localhost:3000/
    
    
    {
      "author": "CarlosVldz",
      "name": "simplesecureapirest",
      "description": "A simple API REST",
      "version": "1.0.0"
    }
    

    노드를 사용하여 모델과 솔리드를 생성합니다.Js


    모델은 데이터베이스의 표시로 단일 기록/문서를 나타낸다.이 예에서, 우리는 하나의 집합을 사용하여 사용자의 정보를 저장하고, 다른 집합을 사용하여 도서 정보를 저장할 것이다.
    해당 필드가 있는 사용자 모델을 만듭니다(새 사용자를 만들 때 모델의 인스턴스를 만듭니다).
    프로젝트 디렉터리에서 모델 폴더와 사용자를 만듭니다.js 파일.
    const mongoose = require('mongoose');
    const bcrypt = require('bcryptjs');
    
    
    // Define Schema
    const userSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true,
            trim: true
        },
        email: {
            type: String,
            required: true,
            trim: true
        },
        password: {
            type: String,
            required: true,
            trim: true
        }
    });
    
    
    // Hash password before save in DB
    userSchema.statics.encryptPassword = async (password) => {
        const salt = await bcrypt.genSalt(10)
        return await bcrypt.hash(password, salt)
    };
    
    
    // Compare password 
    userSchema.statics.comparePassword = async (password, receivedPassword) => {
        return await bcrypt.compare(password, receivedPassword)
    };
    
    
    module.exports = mongoose.model('User', userSchema);
    

    컨트롤러 만들기


    프로젝트 디렉터리에서 이전 auth에서 만든 모델을 위한 폴더 컨트롤러와 컨트롤러를 만듭니다.제어기.js
    이 컨트롤러에서 우리는 두 가지 방법을 정의하여 사용자 '등록' 을 만들거나 등록하고 세션 '로그인' 을 검증하거나 시작할 것입니다.
    const User = require('../models/User');
    const jwt = require('jsonwebtoken');
    
    
    exports.signUp = async (req, res) => {
        const { name, email, password } = req.body;
    
    
        const newUser = new User({
            name, email, password: await User.encryptPassword(password)
        })
    
    
        const savedUser = await newUser.save();
        console.log(savedUser);
    
    
        const newToken = jwt.sign({ id: savedUser._id }, 'secretKey', {
            expiresIn: 86400 // one day
        })
    
    
        res.status(200).json({ newToken })
    }
    
    
    exports.logIn = async (req, res) => {
        const userExist = await User.findOne({ email: req.body.email });
    
    
        if (!userExist) return res.status(400).json({
            message: 'User not exists'
        })
    
    
        const matchPassword = await User.comparePassword(req.body.password, userExist.password)
    
    
        if (!matchPassword) return res.status(401).json({
            token: null,
            message: 'Invalid password'
        })
        console.log(userExist)
    
    
        const token = jwt.sign({ id: userExist._id }, 'secretKey', {
            expiresIn: 86400
        })
    
    
        return res.json({
            _id: userExist._id,
            name: userExist._id,
            message: 'Auth Succesful',
            token: token
        })
    
    }
    

    라우팅 작성


    Google은 디렉터리에 폴더 루트와 파일auth를 만드는 이전 방법의 루트를 계속 만들 것입니다.노선js
    const express = require('express');
    
    
    const router = express.Router();
    
    
    const authCtrl = require('../controllers/auth.controller');
    
    
    router.post('/signup', authCtrl.signUp);
    
    
    router.post('/login', authCtrl.logIn);
    
    
    
    module.exports = router;
    

    도서 수집의 묵은 때를 만들다


    이것으로 우리는 데이터를 만들고, 읽고, 업데이트하고, 삭제할 수 있으며, controllers 폴더에 파일북을 만들 수 있다.제어기.js
    const Book = require('../models/Book');
    
    
    exports.findAllBooks = async (req, res) => {
        try {
            const books = await Book.find();
            res.json(books)
        } catch (error) {
            res.status(500).json({
                message: error.message || "Something goes wrong retieving the tasks"
            })
        }
    };
    
    
    exports.createBook = async (req, res) => {
        try {
            const newBook = new Book({
                name: req.body.name,
                author: req.body.author,
                status: req.body.status ? req.body.status : false
            });
            const bookSaved = await newBook.save();
            res.json(bookSaved)
        } catch (error) {
            res.status(500).json({
                message: error.message || "Something goes wrong creating a book"
            })
        }
    };
    
    
    exports.findOneBook = async (req, res) => {
        const { id } = req.params;
        try {
            const book = await Book.findById(id)
            if(!book) return res.status(404).json({
                message: `Book with id ${id} does not exists!`
            });
            res.json(book)
        } catch (error) {
            res.status(500).json({
                message: error.message || `Error retrieving book with id: ${id}`
            })
        }
    };
    
    
    exports.deleteBook = async (req, res) => {
        const { id } = req.params;
        try {
            const data = await Book.findByIdAndDelete(id)
            res.json({
                message: `${data.name} - Book were deleted successfully!`
            })
        } catch (error) {
            res.status(500).json({
                message: `Cannot delete book with id ${id}`
            })
        }
    }
    
    
    exports.updateBook = async (req, res) => {
        const {id} = req.params;
        try {
            await Book.findByIdAndUpdate(id, req.body)
        res.json({
            message: "Book was updated successfully"
        })
        } catch (error) {
            res.status(500).json({
                message: `Cannot update book with id: ${id}`
            })
        }
    }
    
    책의 모델을 만듭니다.폴더 모형의 js
    const mongoose = require('mongoose');
    
    
    // Define schema
    const bookSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true,
            trim: true
        },
        author: {
            type: String,
            required: true,
            trim: true
        },
        status: {
            type: Boolean,
            default: false
        }
    });
    
    module.exports = mongoose.model('Book', bookSchema);
    
    책의 기록을 위한 루트 프로세서를 만듭니다.노선js
    const express = require('express');
    
    
    const router = express.Router();
    
    
    const bookCtrl = require('../controllers/book.controller');
    
    
    router.get('/', bookCtrl.findAllBooks);
    
    
    router.get('/:id', bookCtrl.findOneBook);
    
    
    router.post('/', bookCtrl.createBook);
    
    
    router.put('/:id', bookCtrl.updateBook);
    
    
    router.delete('/:id', bookCtrl.deleteBook);
    
    
    module.exports = router;
    
    서버를 수정합니다.js 파일은 마지막 단계에서 만든 새 경로를 추가합니다.
    const express = require('express');
    const morgan = require('morgan');
    const mongoose = require('./config/database');
    const pkg = require('../package.json');
    
    
    const authRoutes = require('./routes/auth.routes');
    const bookRoutes = require('./routes/book.routes');
    
    
    const app = express();
    
    
    // DB settings
    mongoose.connection.on('error', console.error.bind(console, 'DB Connection Errror'));
    
    
    // Settings
    app.set('pkg', pkg);
    
    
    // Middleware
    app.use(morgan('dev'));
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    
    
    // Routes
    app.use('/api/auth', authRoutes);
    app.use('/api/books', bookRoutes);
    
    
    // Welcome Route
    app.get('/', (req, res) => {
        res.json({
            author: app.get('pkg').author,
            name: app.get('pkg').name,
            description: app.get('pkg').description,
            version:app.get('pkg').version
        })
    })
    
    
    app.listen(3000, () => { console.log('Server running on port: 3000')
    
    });
    
    데이터베이스에 연결된 프로필과 중간부품을 만들어서 JWT를 검증합니다. 이 파일은 기록에 있는 모든 책을 만들고 수정하며 삭제할 수 있는 권한을 부여합니다.
    한 권이나 모든 책의 경로를 열거할 때 참고 표시를 제공할 필요가 없습니다.
    루트 디렉터리에 설정 폴더와 데이터베이스를 만듭니다.js 파일.
    const mongoose = require('mongoose');
    
    
    // Config DB Connection
    const mongoDB = 'mongodb://localhost/secureAPI';
    
    mongoose.connect(mongoDB, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useFindAndModify: false,
        useCreateIndex: true
    });
    mongoose.Promise = global.Promise;
    
    
    module.exports = mongoose;
    
    그리고 authToken에서 중간부품 폴더와js 파일.
    const jwt = require('jsonwebtoken');
    const User = require('../models/User');
    
    
    exports.verifyToken = async (req, res, next) => {
        try {
            const token = req.headers["x-access-token"];
        if (!token) return res.status(403).json({
            message: "No token provided"
        })
            const decoded = jwt.verify(token, 'secretKey')
            req.userId = decoded.id;
    
    
            const user = await User.findById(req.userId, { password: 0 })
            if (!user) return res.status(404).json({
                message: "No user found"
            })
            next();
        } catch (error) {
            return res.status(401).json({
                message: "Unauthorized"
            })
        }
    }
    
    마지막으로 우리는 우리의 책을 수정했다.노선js 파일로 보호된 경로를 지정합니다.
    const express = require('express');
    
    
    const router = express.Router();
    
    
    const bookCtrl = require('../controllers/book.controller');
    const authToken = require('../middleware/authToken');
    
    
    router.get('/', bookCtrl.findAllBooks);
    
    
    router.get('/:id', bookCtrl.findOneBook);
    
    
    router.post('/', [authToken.verifyToken], bookCtrl.createBook);
    
    
    router.put('/:id', [authToken.verifyToken], bookCtrl.updateBook);
    
    
    router.delete('/:id', [authToken.verifyToken], bookCtrl.deleteBook);
    
    
    
    module.exports = router;
    
    API 테스트
    내 예에서, 나는 Postman을 사용하지만, 불면증이나 다른 도구를 사용해서 REST 서비스를 테스트할 수 있다.
    몇 가지 작업에 대해 살펴보겠습니다.
    모든 책을 열거하다

    잘못된 영패를 제공하지 않도록

    어떠한 기호화폐도 제공하지 않도록 방지하다

    아래 링크에서는 책과 새 사용자의 로그인 및 등록을 위한 모든 경로를 포함하는 API 문서를 찾을 수 있습니다.
    https://documenter.getpostman.com/view/12403851/TVsxBRaR
    my GitHub 에서 전체 코드를 찾을 수 있습니다.

    좋은 웹페이지 즐겨찾기