تخطي إلى المحتوى
Integration

كيفية اكتشاف مستخدمي VPN في تطبيقك من خلال استدعاء API واحد

| 7 min read

أضف اكتشاف VPN والوكيل وTor لتدفقات الاشتراك والخروج وتسجيل الدخول. البرمجيات الوسيطة السريعة، وتكامل Next.js، وأمثلة تسجيل المخاطر باستخدام كود العمل.

Lock icon on a digital network background representing VPN security
Photo by Towfiqu barbhuiya on Unsplash

تحصل صفحة الدفع الخاصة بك على 50 طلبًا من نفس نطاق IP خلال 12 ساعة، وكل ذلك باستخدام بطاقات الدفع المسبق. تعرض النسخة التجريبية المجانية 200 عملية اشتراك من عناوين IP لمراكز البيانات في أسبوع. ترى نقطة نهاية تسجيل الدخول الخاصة بك محاولات حشو بيانات الاعتماد من خلال تدوير عناوين IP للوكيل.

أنت بحاجة إلى معرفة متى تأتي حركة المرور من عقدة خروج VPN أو وكيل أو Tor. لا لمنع ذلك صريح، ولكن لضبط درجة المخاطر الخاصة بك. مكالمة واحدة لواجهة برمجة التطبيقات (API) تمنحك تلك الإشارة.

استدعاء API

أرسل IP الخاص بالمستخدم إلى POST /v1/vpn-detect. لا تبعيات، لا SDK المطلوبة.

curl -X POST https://api.botoi.com/v1/vpn-detect \\
  -H "Content-Type: application/json" \\
  -d '{"ip": "185.220.101.1"}'

الاستجابة لعقدة خروج Tor المعروفة (درجة المخاطرة 90):

{
  "success": true,
  "data": {
    "ip": "185.220.101.1",
    "is_vpn": true,
    "is_proxy": false,
    "is_tor": true,
    "is_datacenter": false,
    "provider": null,
    "risk_score": 90,
    "checks": {
      "tor": true,
      "datacenter": false,
      "suspicious_hostname": false
    }
  }
}

الاستجابة لعنوان IP سكني نظيف (درجة المخاطرة 0):

{
  "success": true,
  "data": {
    "ip": "73.162.45.118",
    "is_vpn": false,
    "is_proxy": false,
    "is_tor": false,
    "is_datacenter": false,
    "provider": null,
    "risk_score": 0,
    "checks": {
      "tor": false,
      "datacenter": false,
      "suspicious_hostname": false
    }
  }
}

يمنحك الرد خمس علامات منطقية (is_vpn, is_proxy, is_tor, is_datacenter) بالإضافة إلى رقم risk_score من 0 إلى 100. اتصالات Tor تحصل على 90. عناوين IP لمراكز البيانات تحصل على 60. أسماء المضيفين المشبوهة النتيجة 40. نقاط IP السكنية النظيفة 0.

التكامل 1: البرمجيات الوسيطة السريعة

تستدعي هذه البرامج الوسيطة واجهة برمجة تطبيقات الكشف عن VPN وترفق النتيجة بها req.vpnRisk. يمكن لكل معالج مسار المصب التحقق req.vpnRisk.isVpn لاتخاذ القرارات دون تكرار استدعاء API.

import type { Request, Response, NextFunction } from 'express';

const VPN_DETECT_URL = 'https://api.botoi.com/v1/vpn-detect';
const BOTOI_API_KEY = process.env.BOTOI_API_KEY;

interface VpnRisk {
  isVpn: boolean;
  isProxy: boolean;
  isTor: boolean;
  isDatacenter: boolean;
  riskScore: number;
}

declare global {
  namespace Express {
    interface Request {
      vpnRisk?: VpnRisk;
    }
  }
}

export async function vpnDetectMiddleware(
  req: Request,
  _res: Response,
  next: NextFunction
) {
  const ip = req.headers['x-forwarded-for']?.toString().split(',')[0]?.trim()
    || req.socket.remoteAddress
    || 'unknown';

  try {
    const res = await fetch(VPN_DETECT_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': \`Bearer \${BOTOI_API_KEY}\`,
      },
      body: JSON.stringify({ ip }),
      signal: AbortSignal.timeout(3000),
    });

    const { data } = await res.json();

    req.vpnRisk = {
      isVpn: data.is_vpn,
      isProxy: data.is_proxy,
      isTor: data.is_tor,
      isDatacenter: data.is_datacenter,
      riskScore: data.risk_score,
    };
  } catch {
    // Fail open: if detection fails, treat as clean
    req.vpnRisk = {
      isVpn: false,
      isProxy: false,
      isTor: false,
      isDatacenter: false,
      riskScore: 0,
    };
  }

  next();
}

// Usage in your route:
// app.use(vpnDetectMiddleware);
//
// app.post('/api/signup', (req, res) => {
//   if (req.vpnRisk?.isVpn) {
//     // require email verification or flag for review
//   }
// });

فشل الوسيطة مفتوحة. إذا تعذر الوصول إلى واجهة برمجة التطبيقات (API) أو انتهت المهلة بعد 3 ثوانٍ، فسيتم تعيينها جميع الأعلام ل false ويتيح استمرار الطلب. لا يرى المستخدمون أي خطأ أبدًا بسبب انقطاع طرف ثالث.

التكامل 2: حماية الخروج Next.js

يتبع الاحتيال في عملية الدفع نمطًا: حساب جديد، وبطاقة مدفوعة مسبقًا، واتصال VPN. هذا Next.js يتحقق معالج مسار جهاز توجيه التطبيق من الإشارات الثلاثة ويوجه الطلبات المشبوهة يدويًا المراجعة بدلاً من الموافقة عليها تلقائيًا.

import { NextRequest, NextResponse } from 'next/server';

const VPN_DETECT_URL = 'https://api.botoi.com/v1/vpn-detect';
const BOTOI_API_KEY = process.env.BOTOI_API_KEY!;

interface CheckoutBody {
  cardType: 'credit' | 'debit' | 'prepaid';
  accountCreatedAt: string;
  amount: number;
  currency: string;
}

export async function POST(req: NextRequest) {
  const body: CheckoutBody = await req.json();

  const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim()
    || '127.0.0.1';

  // Check VPN status
  const vpnRes = await fetch(VPN_DETECT_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': \`Bearer \${BOTOI_API_KEY}\`,
    },
    body: JSON.stringify({ ip }),
    signal: AbortSignal.timeout(3000),
  });

  const { data: vpnData } = await vpnRes.json();

  const accountAge = Date.now() - new Date(body.accountCreatedAt).getTime();
  const isNewAccount = accountAge < 24 * 60 * 60 * 1000; // less than 24 hours
  const isPrepaid = body.cardType === 'prepaid';
  const isVpn = vpnData.is_vpn || vpnData.is_tor || vpnData.is_proxy;

  // VPN + new account + prepaid card = manual review
  if (isVpn && isNewAccount && isPrepaid) {
    return NextResponse.json({
      status: 'review',
      orderId: crypto.randomUUID(),
      message: 'Order placed. We will confirm within 30 minutes.',
    }, { status: 202 });
  }

  // VPN + new account (no prepaid) = proceed with logging
  if (isVpn && isNewAccount) {
    console.log(JSON.stringify({
      event: 'checkout_vpn_new_account',
      ip,
      riskScore: vpnData.risk_score,
      amount: body.amount,
    }));
  }

  // Process the order normally
  return NextResponse.json({
    status: 'approved',
    orderId: crypto.randomUUID(),
  });
}

المعالج لا يرفض الطلب. تقوم بإرجاع 202 مع عبارة "سنؤكد خلال 30 دقيقة" رسالة. يتيح ذلك لفريقك وقتًا للمراجعة دون الإبلاغ عن ممثل سيئ كانوا عليه تم وضع علامة عليها. لا يزال العملاء الشرعيون على شبكات VPN يتلقون معالجة طلباتهم بعد تأخير قصير.

التكامل 3: تحديد معدل تسجيل الدخول

غالبًا ما تأتي هجمات حشو بيانات الاعتماد من VPN أو عناوين IP للوكيل لتجنب الحظر المستند إلى IP. قم بتطبيق حدود أسعار أكثر صرامة على تلك الاتصالات: 3 محاولات تسجيل دخول لكل 15 دقيقة لمستخدمي VPN مقابل 10 للمستخدمين العاديين.

import type { Request, Response, NextFunction } from 'express';

const VPN_DETECT_URL = 'https://api.botoi.com/v1/vpn-detect';
const BOTOI_API_KEY = process.env.BOTOI_API_KEY;

// VPN users: 3 attempts per 15 minutes
// Regular users: 10 attempts per 15 minutes
const VPN_LOGIN_LIMIT = 3;
const STANDARD_LOGIN_LIMIT = 10;
const WINDOW_MS = 15 * 60 * 1000;

const loginAttempts = new Map<string, { count: number; resetAt: number }>();

export async function loginRateLimit(
  req: Request,
  res: Response,
  next: NextFunction
) {
  const ip = req.headers['x-forwarded-for']?.toString().split(',')[0]?.trim()
    || req.socket.remoteAddress
    || 'unknown';

  // Check VPN status
  let isVpn = false;
  try {
    const vpnRes = await fetch(VPN_DETECT_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': \`Bearer \${BOTOI_API_KEY}\`,
      },
      body: JSON.stringify({ ip }),
      signal: AbortSignal.timeout(2000),
    });

    const { data } = await vpnRes.json();
    isVpn = data.is_vpn || data.is_tor || data.is_proxy;
  } catch {
    // Fail open: use standard limits
  }

  const limit = isVpn ? VPN_LOGIN_LIMIT : STANDARD_LOGIN_LIMIT;
  const now = Date.now();
  const entry = loginAttempts.get(ip);

  if (!entry || entry.resetAt < now) {
    loginAttempts.set(ip, { count: 1, resetAt: now + WINDOW_MS });
    return next();
  }

  entry.count++;

  if (entry.count > limit) {
    const retryAfter = Math.ceil((entry.resetAt - now) / 1000);
    return res.status(429).json({
      error: 'Too many login attempts. Try again later.',
      retryAfter,
    });
  }

  next();
}

// Mount on your login route:
// app.post('/api/auth/login', loginRateLimit, loginHandler);

تعمل نسبة 3:10 على إبطاء الهجمات الآلية من عناوين VPN IP دون التأثير على معظم المستخدمين الحقيقيين. المستخدم الشرعي على شبكة VPN الخاصة بالشركة والذي أخطأ في كتابة كلمة المرور الخاصة به ثلاث مرات لا يزال يحصل على رسالة خطأ واضحة ونافذة لإعادة المحاولة، وليس حظرًا دائمًا.

بناء درجة المخاطر المركبة

يعد اكتشاف VPN وحده بمثابة إشارة احتيال ضعيفة. يقوم العديد من المستخدمين الشرعيين بتشغيل شبكات VPN. تحصل الإشارة أقوى عند دمجها مع الشيكات الأخرى. استدعاء ثلاث نقاط نهاية botoi بالتوازي:

  • /v1/vpn-detect لنوع الاتصال (VPN، وكيل، تور، مركز البيانات)
  • /v1/disposable-email/check لجودة البريد الإلكتروني (الرمي مقابل الدائم)
  • /v1/ip/lookup لعدم التطابق الجغرافي (بلد IP مقابل بلد إرسال الفواتير)

تستدعي هذه الوظيفة الثلاثة جميعها وتنتج درجة مخاطرة تتراوح من 0 إلى 100:

interface RiskResult {
  score: number;
  action: 'allow' | 'review' | 'block';
  signals: {
    vpn: boolean;
    tor: boolean;
    proxy: boolean;
    vpnRiskScore: number;
    disposableEmail: boolean;
    geoMismatch: boolean;
    ipCountry: string;
    billingCountry: string;
  };
}

async function calculateRisk(
  ip: string,
  email: string,
  billingCountry: string
): Promise<RiskResult> {
  const BOTOI_KEY = process.env.BOTOI_API_KEY!;
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': \`Bearer \${BOTOI_KEY}\`,
  };

  // Run all three checks in parallel
  const [vpnRes, emailRes, geoRes] = await Promise.all([
    fetch('https://api.botoi.com/v1/vpn-detect', {
      method: 'POST',
      headers,
      body: JSON.stringify({ ip }),
    }),
    fetch('https://api.botoi.com/v1/disposable-email/check', {
      method: 'POST',
      headers,
      body: JSON.stringify({ email }),
    }),
    fetch('https://api.botoi.com/v1/ip/lookup', {
      method: 'POST',
      headers,
      body: JSON.stringify({ ip }),
    }),
  ]);

  const vpnData = (await vpnRes.json()).data;
  const emailData = (await emailRes.json()).data;
  const geoData = (await geoRes.json()).data;

  const ipCountry = geoData.country_code || '';
  const geoMismatch = ipCountry !== '' && billingCountry !== ''
    && ipCountry.toUpperCase() !== billingCountry.toUpperCase();

  // Weight each signal
  let score = 0;

  // VPN/proxy/Tor: up to 30 points
  if (vpnData.is_vpn || vpnData.is_tor || vpnData.is_proxy) {
    score += Math.round(vpnData.risk_score * 0.3);
  }

  // Disposable email: 25 points
  if (emailData.is_disposable) {
    score += 25;
  }

  // Geo mismatch (IP country != billing country): 20 points
  if (geoMismatch) {
    score += 20;
  }

  // VPN + disposable email combo: extra 15 points
  if ((vpnData.is_vpn || vpnData.is_tor) && emailData.is_disposable) {
    score += 15;
  }

  score = Math.min(score, 100);

  return {
    score,
    action: score > 70 ? 'block' : score > 30 ? 'review' : 'allow',
    signals: {
      vpn: vpnData.is_vpn,
      tor: vpnData.is_tor,
      proxy: vpnData.is_proxy,
      vpnRiskScore: vpnData.risk_score,
      disposableEmail: emailData.is_disposable,
      geoMismatch,
      ipCountry,
      billingCountry,
    },
  };
}

// Example usage:
// const risk = await calculateRisk('185.220.101.1', 'user@tempmail.com', 'US');
// if (risk.action === 'review') { queueForManualReview(orderId); }
// if (risk.action === 'block') { rejectTransaction(orderId); }

تعمل جميع مكالمات API الثلاثة بالتوازي مع Promise.all، لذا فإن الكمون الإجمالي يساوي أبطأ مكالمة (عادةً أقل من 100 مللي ثانية). تعتبر أوزان التهديف نقطة البداية. ضبطهم بناءً على بيانات الاحتيال الخاصة بك. إذا كانت رسائل البريد الإلكتروني التي يمكن التخلص منها هي المصدر الأكبر لعمليات رد المبالغ المدفوعة، فقم بزيادة هذه المبالغ هذا الوزن. إذا كانت حالات عدم التطابق الجغرافي نادرة وعادةً ما تكون ضارة بقاعدة المستخدمين لديك، فقم بتقليلها.

متى لا يتم حظر مستخدمي VPN

يعد الحظر الصارم لحركة مرور VPN خطأً بالنسبة لمعظم التطبيقات. فيما يلي الأسباب الشائعة يتصل الأشخاص عبر VPN:

  • سياسة الشركة. Companies route employee traffic through a VPN by default. يعني حظر هذه الاتصالات أن عملاء B2B لا يمكنهم استخدام منتجك أثناء ساعات العمل.
  • خصوصية. يقوم المستخدمون المهتمون بالخصوصية بتشغيل شبكات VPN على كل اتصال كخط أساسي تدبير أمني. إنهم يدفعون للعملاء، وليس المحتالين.
  • تقييد الوصول إلى الإنترنت. يعتمد المستخدمون في بعض البلدان على شبكات VPN للوصول المنتج الخاص بك على الإطلاق. يؤدي حظر شبكات VPN إلى قفلها بالكامل.
  • خدمة الواي فاي العامة. يجب على أي شخص في مقهى أو شبكة المطار أن يستخدم VPN. ومعاقبتهم بسبب النظافة الأمنية الجيدة يخلق حافزا خاطئا.
  • الصحفيين والباحثين. يستخدم الأشخاص في هذه الأدوار Tor وVPN حماية المصدر والأمن التشغيلي. يمكن أن يكون لحظرهم عواقب كبيرة.

النهج الصحيح: رفع العلم والتسجيل، لا تصد بقوة. استخدم اكتشاف VPN كمدخل واحد لـ وظيفة المخاطر التي تأخذ بعين الاعتبار إشارات متعددة. توجيه المعاملات عالية المخاطر إلى قائمة انتظار المراجعة. دع البشر يتخذون القرار النهائي في الحالات الغامضة.

النقاط الرئيسية

  • POST /v1/vpn-detect يعود is_vpn, is_proxy, is_tor, is_datacenter، و risk_score لأي IP.
  • لا يوجد مفتاح API مطلوب للاختبار (5 طلبات في الدقيقة). تفتح المفاتيح المجانية حدودًا أعلى للإنتاج.
  • قم بإرفاق فحص VPN بالبرنامج الوسيط Express حتى يتمكن كل مسار من الوصول إلى بيانات المخاطر دون تكرار المكالمة.
  • ادمج اكتشاف VPN مع عمليات التحقق من البريد الإلكتروني التي يمكن التخلص منها وتحديد الموقع الجغرافي عبر IP للمجمع درجة المخاطرة قوية بما يكفي للعمل بناءً عليها.
  • ضع علامة على اتصالات VPN للمراجعة. لا تمنعهم. يقوم المستخدمون الشرعيون بتشغيل شبكات VPN لـ الخصوصية وسياسة الشركة والوصول المحدود إلى الإنترنت.

FAQ

كيف يمكنني اكتشاف مستخدمي VPN في تطبيقي؟
أرسل عنوان IP الخاص بالمستخدم في طلب POST إلى نقطة نهاية botoi /v1/vpn-detect. تتضمن الاستجابة علامات منطقية لـ is_vpn وis_proxy وis_tor وis_datacenter، بالإضافة إلى 0-100 Risk_score. قم باستدعاء نقطة النهاية هذه أثناء التسجيل أو تسجيل الدخول أو الخروج لوضع علامة على الاتصالات من خدمات إخفاء الهوية.
ما هي واجهة برمجة تطبيقات اكتشاف VPN الأفضل لتطبيقات الإنتاج؟
ابحث عن واجهة برمجة التطبيقات (API) التي تُرجع إشارات منفصلة لاتصالات VPN والوكيل وTor ومركز البيانات بدلاً من علامة منطقية واحدة. تقوم نقطة النهاية botoi /v1/vpn-detect بإرجاع جميع العلامات الأربعة بالإضافة إلى درجة المخاطر الرقمية، وتعمل بدون مفتاح API بمعدل 5 طلبات في الدقيقة. بالنسبة لأحمال عمل الإنتاج، تفتح مفاتيح واجهة برمجة التطبيقات (API) حدود المعدل الأعلى بدءًا من الطبقة المجانية.
هل يجب أن أحظر جميع مستخدمي VPN من تطبيقي؟
لا. يقوم العديد من المستخدمين الشرعيين بتشغيل شبكات VPN لأغراض الخصوصية أو سياسة الشركة أو لأنهم يعيشون في مناطق ذات وصول مقيد إلى الإنترنت. يؤدي حظر كل حركة مرور VPN إلى إغلاق العملاء الذين يدفعون. بدلاً من ذلك، استخدم اكتشاف VPN كإشارة واحدة في درجة المخاطر المركبة وقم بوضع علامة على الاتصالات المشبوهة للمراجعة.
هل يمكنني اكتشاف اتصالات الوكيل وTor بنفس استدعاء واجهة برمجة التطبيقات؟
نعم. تقوم نقطة نهاية botoi /v1/vpn-detect بإرجاع إشارات منطقية منفصلة لـ is_vpn وis_proxy وis_tor في استجابة واحدة. لا تحتاج إلى استدعاءات API منفصلة لكل نوع اتصال. تقوم نقطة النهاية أيضًا بإرجاع is_datacenter لتحديد حركة المرور من موفري الخدمات السحابية مثل AWS أو Google Cloud.
كيف يمكنني الجمع بين اكتشاف VPN وإشارات الاحتيال الأخرى؟
اتصل بنقاط نهاية botoi المتعددة بالتوازي: /v1/vpn-detect لنوع الاتصال، و/v1/disposable-email/تحقق من جودة البريد الإلكتروني، و/v1/ip/lookup لعدم التطابق الجغرافي بين بلد IP وبلد إرسال الفواتير. وزن كل إشارة وجمعها في درجة المخاطرة 0-100. الدرجات الأعلى من 70 تذهب إلى المراجعة اليدوية؛ تمر الدرجات أقل من 30.

ابدأ البناء مع botoi

أكثر من 150 نقطة نهاية API للبحث ومعالجة النصوص وتوليد الصور وأدوات المطورين. باقة مجانية، بدون بطاقة ائتمان.