چگونه یک کلاینت OAuth بسازیم
نسخهٔ API 2026-10-affable-towhee
پیش از آنکه در صفحهٔ یکپارچهسازیها «ساخت کلاینت» را بزنید، سه چیز را تعیین کنید: کلاینت اجازهٔ چه کاری دارد، کدام فرایند رمز آن را نگه میدارد، و هزینهٔ فراخوانیهایش را چه کسی میپردازد. راهنمای احراز هویت قاعدهها را بیان میکند؛ این صفحه آنها را بر دو شرکت خیالی، Luba و Farducks، پیاده میکند.
Luba: Dive Deck
Luba زیردریاییهای خودران را بهعنوان خدمت حملونقل و سفر اشتراکی اداره میکند. Dive Deck آن روی صفحهٔ کابین به هر مسافر عبارتی از همان غوص را نشان میدهد، به زبانی که در حال یادگرفتنش است، و تیم عملیات Luba زیر نظر دارد که چه مقدار از سهمیه باقی مانده است.
Luba یک کلاینت میسازد، Luba Dive Deck، با اجازهٔ «تولید واژگان» (vocab:generate) و «خواندن میزان استفاده» (usage:read) و صورتحساب روی «سهمیهی طرح شما» (allowance). دو فرایند در آن شریکاند و هر کدام هنگام مبادله فقط دامنهای را میخواهد که لازم دارد. مبادلهای که scope را نفرستد همهٔ دامنههای مجاز کلاینت را میگیرد؛ مبادلهای که دامنهای را بخواهد که برای کلاینت مجاز نیست بهطور کامل با invalid_scope رد میشود و هرگز بیصدا محدود نمیشود.
سرور اعزام عبارتهای هر غوص را مینویسد. فقط vocab:generate را میخواهد، پس توکنی که از آن نشت کند نمیتواند میزان استفادهٔ Luba را بخواند.
export LINGARA_TOKEN="$(curl -sS --fail-with-body -X POST "https://api.getlingara.com/oauth/token" \
-u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=vocab:generate" | jq -r '.access_token // error(.error)')"curl -N -X POST "https://api.getlingara.com/v1/vocab/stream" \
-H "Authorization: Bearer $LINGARA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"level":2,"source_lang":"en","target_lang":"zh","count":8}'داشبورد عملیات فرایند دومی در سمت سرور با همان شناسهٔ کلاینت و رمز است. فقط usage:read را میخواهد و مقدار باقیماندهٔ سهمیه را میخواند.
export LINGARA_TOKEN="$(curl -sS --fail-with-body -X POST "https://api.getlingara.com/oauth/token" \
-u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=usage:read" | jq -r '.access_token // error(.error)')"curl "https://api.getlingara.com/v1/usage" \
-H "Authorization: Bearer $LINGARA_TOKEN"هر دو فرایند روی سرورهای Luba اجرا میشوند. تبلت داخل کابین عبارتها را از سرور اعزام میخواهد و هرگز رمز یا توکنی نگه نمیدارد، چون هر چیزی روی دستگاهی که مسافر بتواند به آن دست بزند خواندنی است. بخش «رمزها و توکنها را روی سرور نگه دارید» در راهنمای احراز هویت دلیلش را توضیح میدهد.
همین کلاینت بهصورت پروژهای که میتوانید کلون و اجرا کنید: integrations/luba-dive-deck
Farducks: Batter Rewards
Farducks زنجیرهای از فروشگاههای کوچک ماهی و سیبزمینی سرخکرده است. تا سفارش سرخ میشود، اپ وفاداری Batter Rewards از بکاند خود Farducks یک طرح درس کوتاه میخواهد و سپس آن را میخواند. اپ و صندوقها بکاند Farducks را فرا میخوانند، هرگز Lingara را، پس هیچکدام رمز را نگه نمیدارند.
Farducks یک کلاینت میسازد، Farducks Batter Rewards، با اجازهٔ «ساخت برنامههای درسی» (lesson_plans:write) و «خواندن برنامههای درسی» (lesson_plans:read) و صورتحساب روی «سهمیهی طرح شما» (allowance). امروز این تنها روش صورتحسابی است که میتوان کلاینت را با آن ساخت، و روش صورتحساب هر کلاینت هنگام ساختنش ثابت میشود. روش دیگر، metered («پرداخت بر اساس مصرف»)، در بخش «هزینهٔ فراخوانی را چه کسی میپردازد» در راهنمای احراز هویت شرح داده شده است.
بکاند فقط lesson_plans:write را میخواهد و طرح را میسازد. پاسخ بهصورت جریانی میآید و رویداد started آن plan_id طرح را در خود دارد.
export LINGARA_TOKEN="$(curl -sS --fail-with-body -X POST "https://api.getlingara.com/oauth/token" \
-u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=lesson_plans:write" | jq -r '.access_token // error(.error)')"curl -N -X POST "https://api.getlingara.com/v1/lesson-plans" \
-H "Authorization: Bearer $LINGARA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"context":"Ordering food at a night market","source_lang":"en","target_lang":"zh","level":2}'ID را برابر همان plan_id قرار دهید، سپس lesson_plans:read را بخواهید و طرح را بخوانید. یک مبادله میتواند چند دامنه از دامنههای کلاینت را بخواهد، با فاصله از هم جدا در scope؛ هر فرمان در اینجا یک دامنه میخواهد، چون هر کدام از یک فراخوانی ساخته شده است.
export LINGARA_TOKEN="$(curl -sS --fail-with-body -X POST "https://api.getlingara.com/oauth/token" \
-u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=lesson_plans:read" | jq -r '.access_token // error(.error)')"curl "https://api.getlingara.com/v1/lesson-plans/$ID" \
-H "Authorization: Bearer $LINGARA_TOKEN"روزی رمز در یک تیکت پشتیبانی چسبانده میشود. Farducks در صفحهٔ یکپارچهسازیها «رمز جدید» را میزند و آن را روی بکاند مستقر میکند، صبر میکند تا تاریخ «آخرین استفاده»ی رمز قدیمی دیگر تغییر نکند، سپس روی رمز قدیمی «ابطال» را میزند. از همان لحظه هر توکن دسترسیای که با مبادلهٔ رمز قدیمی گرفته شده بود رد میشود. بخش «چرخاندن رمز» در راهنمای احراز هویت سقف دو رمز و دلیل ممکن نبودن ابطال تنها رمز یک کلاینت را توضیح میدهد.
همین کلاینت بهصورت پروژهای که میتوانید کلون و اجرا کنید: integrations/farducks-batter-rewards
قدم بعدی
راهنمای احراز هویت خطاهای مبادله، کاری که هنگام منقضی شدن توکن باید کرد و قاعدهٔ چرخاندن را پوشش میدهد. راهنمای نسخهها نسخهای را که کلاینت به آن سنجاق شده است، و شیوهٔ انتخاب نسخهای دیگر برای یک فراخوانی را پوشش میدهد.
اگر ترجمه با مرجع انگلیسی تفاوت داشته باشد، مرجع انگلیسی معتبر است.