노드에서 대용량 프로덕션용 어플리케이션에 이르기까지 API 속도 제한js

14841 단어 apiratelimitnode

소개하다.
속도 제한은 백엔드 API가 폭력/login이나 /admin과 같은 악의적인 공격으로부터 보호되고 사용자로부터 불필요한 요청을 처리하는 데 사용되는 가장 중요한 보안 기능 중 하나입니다.간단하게 말하자면, 속도 제한은 우리가 개발자로서 서버로서 사용자의 요청을 처리하는 속도를 제어할 수 있게 한다.
이 가이드에서는 소규모 프로젝트에 속도 제한을 빨리 추가하는 방법과 생산성 있는 응용 프로그램을 확장하는 방법을 배울 것입니다.

당신은 왜 금리 제한을 늘리려고 합니까?
간단히 말하면 DOS 공격의 위험을 낮추고 서버가 과부하되지 않도록 하기를 원합니다.
예를 들어 공용 API를 구축해야 하며 구독하지 않은 사용자가 시간당 100개의 요청만 할 수 있도록 허용해야 합니다.사용자가 이 제한을 초과하면, 이 요청을 간단하게 무시하고, 자유제한이 다 소모되었음을 알리는 오류를 보내고, API나 다른 유사한 것을 구독하는 것을 고려하십시오.
속도 제한 기술을 구현하려면 다음 중 하나를 기준으로 구속이 명시적으로 정의되어 있어야 합니다.

  • IP 주소: 요청이 시작된 장치의 IP 주소로 제한됩니다.

  • 위치: 이곳의 제약은 실현된 지리적 구역에 기초를 두고 있다.
    요청한 장소에서

  • 사용자: 특정 사용자를 구속하고 유일한 식별자를 사용하여 실현
    사용자 ID, API 키 등 특정 사용자용
  • 속도 제한을 실현할 수 있는 몇 가지 알고리즘이 있다. 너는 할 수 있다. read more about them here
    이를 감안하여 API 속도 제한의 실제 실현부터 시작하겠습니다.

    중소기업용
    이를 위해 express-rate-limit라는 제3자 npm 패키지를 사용합니다.물론 우리는 스스로 맞춤형 중간부품을 구축할 수 있지만 바퀴를 재발명할 필요는 없다.

    1단계: 기본 항목 설정
    나는 네가 이미express와 합작하는 프로젝트가 있다고 가정한다.없으면 boilerplate-gen 패키지를 사용하여express 프로젝트를 빠르게 설정합니다.
    npx boilerplate-gen
    
    프로젝트 템플릿으로 express를 선택하십시오.

    2단계: 타사 패키지 설치
    패키지를 설치합니다.
    yarn add express-rate-limit
    

    3단계: 금리 제한 중간부품 만들기
    const rateLimit = require('express-rate-limit');
    
    // Rate limit middleware
    const rateLimitMiddleware = rateLimit({
      windowMs: 60 * 60 * 1000,
      max: 100,
      message: 'You have exceeded your 100 requests per hour limit.',
      headers: true,
    });
    
    // Export it
    module.exports = rateLimitMiddleware;
    
    이제 우리가 여기서 무엇을 하는지 빠르게 알아봅시다.
    가방에 설치된rateLimit 함수를 호출하는 rateLimitMiddleware 함수를 내보내고 있습니다.이 중간부품은 우리가 전송한 옵션에 따라 속도 제한을 강제로 실행합니다. 이 옵션들은 -
  • windowMs - 창 크기가 밀리초 단위로 한 시간입니다.
  • max - 창 크기에 허용되는 최대 요청 수입니다.
  • message - 사용자가 제한을 초과하면 오류 메시지가 표시됩니다.
  • headers - 이 API 리소스의 속도 제한X-RateLimit-Limit, 현재 사용량X-RateLimit-Remaining 및 재시도 전 대기 시간Retry-After을 표시하는 제목을 자동으로 추가합니다.
  • 현재 우리는 중간부품을 만들었습니다. 요청을 처리할 때 이 중간부품을 사용하도록 프로그램을 설정하기만 하면 됩니다.

    4단계: 중간부품 사용
    const express = require('express');
    const rateLimitMiddleware = require('./middlewares/ratelimit');
    
    const app = express();
    // Use Ratelimit Middleware
    app.use(rateLimitMiddleware);
    
    봐라!우리 여기까지.이제 구성에 따라 모든 요청의 속도가 제한됩니다.또한 일부 루트에 서로 다른 설정 집합을 가진 여러 개의 중간부품을 추가할 수 있습니다.
    예를 들어, 정상적인 라우팅은 시간당 100 개의 요청으로 제한되고 /login 또는 /admin 요청은 피하려면 시간당 20 개의 요청으로 제한됩니다brute force password attacks.

    Note: This package identifies users by their IP addresses using req.ip by default


    위대하다이제 API에 대한 속도 제한을 추가하는 간단한 4단계를 수행합니다.
    이제 이 블로그의 반쪽으로, 바로...

    대규모 어플리케이션용
    만약 중소형 응용 프로그램을 구축하고 있다면, 상술한 실현은 매우 좋습니다.그러나 이런 방법은 대형 응용 프로그램으로 확장할 수 없다.
    이게 왜??잘 물어봤을 거야.
    우선, 응용 프로그램이 크면, 하나의 서버에서 하나의 노드 프로세스를 사용하지 않을 수도 있습니다.반대로 분산 시스템에서 여러 노드 프로세스를 실행하고 기본적으로 상기 제3자 패키지는 다른 프로세스/서버와 상태를 공유하지 않습니다.
    따라서 같은 설정을 사용하면 확장할 수 없습니다.
    그러면 해결 방안은 무엇일까요?어떻게 여러 서버의 실례 사이에서 상태를 공유합니까?
    답은 간단합니다.External Data Store를 사용하여 모든 정보를 저장할 수 있습니다.express-rate-limit 패키지는 기본적으로 Memory Store를 사용하고 hits는 노드의 메모리에 저장됩니다.js 프로세스입니다. 따라서 프로세스 간에 상태를 공유할 수 없습니다.
    따라서 우리는 외부 데이터 저장소를 사용하여 이러한 정보를 저장할 수 있다. 그러면 우리는 여러 프로세스/서버가 이 외부 저장소를 사용할 수 있고, 이렇게 하면 우리는 우리의 응용 프로그램을 확장할 수 있다.
    현재의 문제는 우리가 무엇을 우리의 것으로 사용해야 하는가 하는 것이다. Data Store많은 선택이 있다. 예를 들면-
  • Redis상점
  • Memcached Store
  • 몽고 상점
  • PostgreSQL
  • MySQL 등
  • 나는 Redis를 더욱 선택하고 싶다. 왜냐하면 그것은 신속하고 유연하며 각종 유형의 데이터 구조를 지원하기 때문이다.
    또한 Redis,process Memory,Cluster 또는 PM2,Memcached,MongoDB,MySQL,PostgreSQL과 함께 사용하고 단일 프로세스나 분포식 환경에서 요청 속도를 제어할 수 있는 또 다른 제3자 패키지를 사용할 것입니다.
    이제 실현 부분부터 시작해 봅시다.현재 프로젝트가 있거나, 위와 같은 방법으로 새로운 프로젝트를 신속하게 만들 수 있다고 가정하십시오.
    rate-limiter-flexible
    1단계: 패키지 설치
    yarn add rate-limiter-flexible redis
    

    2단계: 중간부품 설정
    프로젝트에서 Redis를 사용할 예정입니다. Redis를 설치하지 않은 경우 우선
    const redis = require('redis');
    const { RateLimiterRedis } = require('rate-limiter-flexible');
    
    // Create redis client
    const redisClient = redis.createClient({
      host: 'redis',
      port: 6379,
    });
    
    // Setup Rate Limiter
    const rateLimiter = new RateLimiterRedis({
      redis: redisClient, // redis client instance
      keyPrefix: 'appname:rl', // prefix your keys with some name
      points: 10, // 10 requests
      duration: 1, // per 1 second by IP
    });
    
    // Setup the middleware using the rate limiter config
    const rateLimiterMiddleware = (req, res, next) => {
      // On the basis of ip address, but can be modified according to your needs
      rateLimiter
        .consume(req.ip)
        .then(() => {
          next();
        })
        .catch(() => {
          res.status(429).send('Too Many Requests');
        });
    };
    
    module.exports = rateLimiterMiddleware;
    
    우리 각 부분에 따라 세분화합시다.
  • 우리는 Redis와rate limiter flexible의 소프트웨어 패키지를 가져왔고 RateLimiterRedis를 사용했다. 왜냐하면 우리는 Redis로 실현했기 때문이다.
  • Redis 기본 포트6379에 로컬 시스템에 연결된 Redis 클라이언트를 만듭니다.여기서는 Redis와 함께 원격 관리 기기를 사용할 수도 있습니다. (대형 시스템에서도 그럴 수 있습니다.)
  • 우리는 일부 설정 옵션을 사용하여rateLimiter 실례를 만들었다
  • redis - 우리가 만든 redisclient 인스턴스입니다.
  • keyPrefix - 접두사를 생성된 모든 키에 추가하면 appname:rl처럼 사용할 수 있습니다.rl은ratefimit를 나타냅니다.다른 키 접두사를 마음대로 선택하십시오.
  • points - 지속 시간 동안 소모할 수 있는 최대 포인트 수입니다.
  • duration - 소모점 이전의 초수를 리셋합니다.0로 설정하면 재설정되지 않습니다.
    자세한 내용 download and install it from here
  • 마지막으로 우리는 우리의 중간부품을 구축했다. 이것은 우리가 위에서 만든rateLimiter의 실례를 사용하고 사용자의 req.ip 즉 IP 주소를 바탕으로 소비한다.
  • 마지막으로, 우리는 app.js에서 이 중간부품을 사용할 것이다
    options here
    3단계: 미들웨어 사용
    const express = require('express');
    const rateLimiterRedisMiddleware = require('./middleware/rateLimiterRedis');
    
    const app = express();
    app.use(rateLimiterRedisMiddleware);
    
    그리고이렇게이제 속도 제한기를 사용하여 프로그램을 확장할 수 있습니다.자세한 정보와 구성 옵션에 대한 자세한 내용은 패키지의 설명서를 확인하는 것이 좋습니다.

    TL;박사 01 명
    우리는 코드 예시를 통해 소형과 대형 응용 프로그램의 NodeJ와expressjs에 속도 제한기를 설정하는 방법을 이해할 것이다.

    링크
  • What is Rate Limiting
  • express-rate-limit
  • rate-limiter-flexible
  • 좋은 웹페이지 즐겨찾기