5 минутад эхлэх

Эхний баталгаажуулалтаа тест API түлхүүрээр, бодит SMS илгээлгүйгээр 5 минутад хийж үзнэ.

Хоёр замаас аль нэгийг сонгоно уу.

  • Виджет: хуудсандаа 10 мөр код нэмнэ. Дугаар оруулах талбар, 150₮ үнэ, код, SMS товч, QR-ыг виджет өөрөө харуулна. Webhook бичих шаардлагагүй.
  • Өөрийн UI: дизайн, урсгалаа бүрэн өөрөө хийнэ. Сервер тань session үүсгэж, үнийн UI-г харуулж, үр дүнг webhook-оор авна.

Хэрэглэгч товчийг дарж утасны дугаараа оруулаад, кодоо тэр утаснаасаа SMS-ээр илгээнэ. Баталгаажмагц таны сервер нэг дуудлагаар дугаарыг авна.

Нэвтрэх

Example сайтад утасны дугаараараа нэвтэрнэ.

Жишээ. Энд SMS илгээгдэхгүй, сервер рүү хүсэлт явахгүй.

API түлхүүр авч, сайтаа нэмэх

Хянах самбар-т нэвтэрч, Виджет хэсэгт pk_test_ угтвартай нийтийн API түлхүүр үүсгэнэ. Виджет ажиллах сайтын хаягийг (жишээ нь http://localhost:3000) жагсаалтад нэмнэ. API түлхүүр хэсгээс серверт зориулсан sk_test_ нууц API түлхүүр үүсгэнэ.

export TWOFA_KEY="sk_test_..."

Тест API түлхүүр оператор руу хэзээ ч хандахгүй, орлого ч тооцохгүй.

Кодоо хуудсандаа тавих

<div id="twofa"></div>
<script src="https://verify.2fa.mn/embed/v1/embed.js"></script>
<script>
  TwoFA.button('#twofa', { key: 'pk_test_...', state: '<session-д хадгалсан санамсаргүй утга>' })
    .on('verified', ({ token }) => fetch('/login', { method: 'POST', body: token }));
</script>

state-ийг сервер тань нэвтрэх оролдлого бүрт шинээр үүсгэж, session-д хадгална. Үнийг харуулах, баталгаажмагц товчийг нуух дүрмийг виджет өөрөө биелүүлнэ.

Хэрэглэгчийн SMS-ийг дуурайх

Товчийг дарж цонхоо нээгээд дугаар оруулна, жишээ нь 99112233. Тест горимд хэрэглэгчийн SMS-ийг POST /v1/test/mo-оор дуурайна. Оруулсан дугаараа from-д, цонхонд харагдаж буй кодыг text-д бичнэ.

curl -X POST https://api.2fa.mn/v1/test/mo \
  -H "Authorization: Bearer $TWOFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "from": "99112233", "text": "482913" }'

Цонх баталгаажсан төлөвт шилжиж хаагдана, verified үйл явдалд token ирнэ.

Сервер дээрээ token-оо солиж, state-ээ шалгах

curl https://api.2fa.mn/v1/verifications/$TOKEN \
  -H "Authorization: Bearer $TWOFA_KEY"
{
  "session_id": "ses_8f3k2m",
  "phone": "99112233",
  "verified_at": "2026-12-01T10:02:14Z",
  "mode": "test",
  "state": "q9Xh2LwP0aT7bV4e"
}

state нь session-д хадгалсан утгатай таарч байвал л хэрэглэгчийг нэвтрүүлнэ. Token нэг л удаа ашиглагдана. Node.js, Python, PHP жишээ болон алдаануудыг Виджет хэсгээс үзнэ үү.

Таны сервер session үүсгэж, үнийн UI-г өөрийн дизайнаар харуулна. Үр дүнг signature-тай webhook-оор хүлээн авна.

Нууц API түлхүүр үүсгэх

Хянах самбар-т нэвтэрч, API түлхүүр хэсгээс sk_test_ угтвартай тест API түлхүүр үүсгэнэ.

export TWOFA_KEY="sk_test_..."

Нууц API түлхүүрийг зөвхөн серверт хадгална. Хөтөч, гар утасны апп, git руу хэзээ ч оруулахгүй.

Webhook хаягаа бүртгэх

2fa.mn үр дүнг таны сервер рүү webhook-оор илгээнэ. Хаягаа бүртгээд хариунд ирэх secret-ийг аюулгүй газар хадгална.

curl -X PUT https://api.2fa.mn/v1/webhook \
  -H "Authorization: Bearer $TWOFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.mn/webhooks/2fa" }'
{ "url": "https://example.mn/webhooks/2fa", "secret": "whsec_..." }

Локал орчинд хөгжүүлж байгаа бол ngrok эсвэл cloudflared зэрэг tunnel ашиглан серверээ нийтийн хаягтай болгоно.

Код үүсгэх

Хэрэглэгч дугаараа баталгаажуулах үед таны сервер session үүсгэнэ.

curl -X POST https://api.2fa.mn/v1/sessions \
  -H "Authorization: Bearer $TWOFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "99112233", "metadata": { "user_id": "u_42" } }'
const res = await fetch('https://api.2fa.mn/v1/sessions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TWOFA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ phone: '99112233', metadata: { user_id: 'u_42' } }),
});
const session = await res.json(); // session.sms_uri, session.code
body := strings.NewReader(`{"phone": "99112233", "metadata": {"user_id": "u_42"}}`)
req, _ := http.NewRequest("POST", "https://api.2fa.mn/v1/sessions", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("TWOFA_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
<?php
$ch = curl_init('https://api.2fa.mn/v1/sessions');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('TWOFA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['phone' => '99112233', 'metadata' => ['user_id' => 'u_42']]),
]);
$session = json_decode(curl_exec($ch), true);
import os, requests

res = requests.post(
    "https://api.2fa.mn/v1/sessions",
    headers={"Authorization": f"Bearer {os.environ['TWOFA_KEY']}"},
    json={"phone": "99112233", "metadata": {"user_id": "u_42"}},
)
session = res.json()  # session["sms_uri"], session["code"]
{
  "id": "ses_8f3k2m",
  "mode": "test",
  "code": "482913",
  "short_code": "150073",
  "sms_uri": "sms:150073?body=482913",
  "status": "pending",
  "phone": "99112233",
  "expires_at": "2026-12-01T10:05:00Z"
}

phone заасан бол зөвхөн тэр дугаараас ирсэн SMS энэ session-ийг баталгаажуулна.

Үнэ болон SMS товчийг харуулах

Үнийг товчийн өмнө харуулж, sms_uri руу холбосон товч гаргана. Энэ нь үйлчилгээний нөхцөлөөр заавал шаардагдана.

<p>Үнэ: 150₮</p>
<a href="sms:150073?body=482913">SMS илгээх</a>

Бэлэн HTML, QR, React кодыг Өөрийн UI бүтээх хэсгээс хуулж авна уу.

Хэрэглэгчийн SMS-ийг дуурайх

curl -X POST https://api.2fa.mn/v1/test/mo \
  -H "Authorization: Bearer $TWOFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "from": "99112233", "text": "482913" }'

Webhook хүлээн авч, signature шалгах

Таны хаяг руу verification.succeeded үйл явдал ирнэ. Боловсруулахаасаа өмнө X-2FA-Signature толгойг заавал шалгана.

server.js
import express from "express";
import crypto from "node:crypto";

const app = express();
const SECRET = process.env.TWOFA_WEBHOOK_SECRET;

app.post("/webhooks/2fa", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("X-2FA-Signature") ?? "";
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(400);

  const expected = crypto
    .createHmac("sha256", SECRET)
    .update(`${t}.${req.body}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1 ?? "");
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(400);

  const event = JSON.parse(req.body);
  if (event.type === "verification.succeeded") {
    // event.data.phone баталгаажлаа. event.id-аар давхардлыг шалгана.
  }
  res.sendStatus(200);
});

app.listen(3000);

Бусад хэл дээрх жишээг Webhook ба signature хэсгээс үзнэ үү.

Бодит орчинд гаргах

  • Виджет: pk_live_ болон sk_live_ API түлхүүр үүсгэж, бодит сайтаа виджетийн жагсаалтад нэмнэ. Token-ийг үргэлж сервер дээрээ солиж, state-ийг шалгана.
  • Өөрийн UI: sk_live_ API түлхүүр үүсгэж, бодит горимын webhook хаягаа тусад нь бүртгэнэ. Үнийг товчийн өмнө харуулж, баталгаажсаны дараа товчийг нууна. Webhook-ийг id-аар давхардуулахгүй боловсруулна.

Дараагийн алхам

Энэ хуудас тус болсон уу?