ورود با OAuth2
افراد را برای ورود به برنامه خود به Hivesigner بفرستید. آنها درخواست شما را آنجا بررسی میکنند و تأیید میکنند. سپس Hivesigner آنها را با یک توکن (جریان توکن) یا با کدی که سرور شما آن را با توکن مبادله میکند (جریان کد) به نشانی بازگشت شما بازمیگرداند. این صفحه هر دو جریان، همه پارامترها و دامنهها را پوشش میدهد.
پیش از آغاز
- برنامه خود را ثبت کنید: یک حساب Hive برای آن، با نشانیهای بازگشت فهرستشده. ببینید برنامه خود را ثبت کنید.
- برای انتشار از راه API، حساب برنامه شما باید به @hivesigner اختیار انتشار هم بدهد.
- برای جریان کد، یک کلید محرمانه کلاینت تنظیم کنید.
نشانی مجوز
کاربر را به این نشانی بفرستید:
https://hivesigner.com/oauth2/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=SCOPE&state=STATE
هر مقدار را با URL رمزگذاری کنید. URLSearchParams این کار را برای شما انجام میدهد:
import { randomBytes } from 'node:crypto';
const state = randomBytes(16).toString('hex');
// Store `state` in the user's session before you redirect (see "Protect the request with state").
const params = new URLSearchParams({
client_id: 'myapp',
redirect_uri: 'https://myapp.example/auth/callback',
scope: 'posting',
state,
});
const authorizeUrl = `https://hivesigner.com/oauth2/authorize?${params}`;
پارامترها
| پارامتر | الزامی | چه میکند |
|---|---|---|
client_id |
بله، برای یک برنامه | نام حساب برنامه شما. clientId هم خوانده میشود. بدون آن، درخواست یک درخواست فقط ورود از سایتی بدون حساب برنامه است: ببینید ورود بدون دسترسی انتشار. |
redirect_uri |
بله | جایی که Hivesigner کاربر را به آن بازمیگرداند. باید دقیقاً یکی از نشانیهای URI بازگشت برنامه شما باشد. ببینید نشانیهای بازگشت. |
scope |
خیر | login، posting یا offline. ببینید دامنهها. بدون آن، درخواست دسترسی انتشار میخواهد. |
response_type |
خیر | مقدار code جریان کد را آغاز میکند. هر مقدار دیگر، یا نبود آن، یعنی جریان توکن. |
state |
توصیهشده | یک مقدار تصادفی که Hivesigner بدون تغییر بازمیگرداند. ببینید درخواست را با state محافظت کنید. |
account |
خیر | یک نام کاربری Hive. وقتی آن حساب روی دستگاه کاربر باشد، Hivesigner آن را انتخاب میکند. در غیر این صورت نادیده گرفته میشود. select_account هم خوانده میشود. |
کاربر همچنان میتواند در صفحه رضایت به حساب دیگری برود. همیشه حساب را از توکن یا از مبادله کد بگیرید، نه از آنچه خواستهاید.
دامنهها
Hive یک اختیار انتشار دارد. به همین دلیل Hivesigner دو سطح دسترسی دارد، فقط ورود و انتشار، و چیز ریزتری میان آن دو نیست.
scope |
آنچه کاربر تأیید میکند | جریان | type توکن دسترسی |
|---|---|---|---|
login |
«مشاهده نام کاربری حساب شما». چیزی داده نمیشود. | جریان توکن (response_type=code نیفزایید) |
login |
posting |
دسترسی انتشار. نخستین بار، این کار حساب برنامه شما را به اختیار انتشار کاربر میافزاید. | جریان توکن، یا جریان کد با response_type=code |
posting |
offline |
دسترسی انتشار، مانند بالا | جریان کد | posting، با یک توکن refresh |
در جریان کد، نشانی بازگشت نخست یک کد میگیرد (توکنی با type برابر code) که سرور شما آن را با توکن دسترسی مبادله میکند.
- نبود دامنه یعنی
posting. - مقداری که در هر جای آن
offlineباشد یعنیoffline، برای نمونهoffline,vote,commentقدیمی. - هر مقدار دیگر یعنی
posting. این شامل نامهای قدیمی عملیات مانندvote،comment،vote,comment،comment_optionsیاcustom_jsonهم میشود. آنها توکن را محدود نمیکنند: هر توکن انتشار همان عملیات را مجاز میکند. ببینید broadcast چه میپذیرد.
وقتی برنامه شما فقط باید بداند کاربر کیست، login بخواهید. ببینید ورود بدون دسترسی انتشار.
جریان توکن
مرورگر کاربر توکن دسترسی را مستقیم میگیرد. برنامه شما به هیچ کلید محرمانهای نیاز ندارد.
-
کاربر را به نشانی مجوز بفرستید:
https://hivesigner.com/oauth2/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=posting&state=STATE -
کاربر تأیید میکند. Hivesigner به نشانی بازگشت شما هدایت میکند:
REDIRECT_URI?state=STATE&access_token=ACCESS_TOKEN&expires_in=604800&username=USERNAMEوقتی نشانی بازگشت شما پرسوجو نداشته باشد Hivesigner پارامترهایش را با
?میافزاید و وقتی داشته باشد با&.stateتنها زمانی هست که مقداری ناتهی فرستاده باشید. -
در نشانی بازگشت، نخست
stateرا مقایسه کنید. سپس توکن را بررسی کنید روی سرور خود. حسابی که توکن برای آن است درون خود توکن است: تنها به پارامترusernameتکیه نکنید، چون هر کسی میتواند یک نشانی را ویرایش کند. -
توکن را روی سرور خود یا در یک کوکی httpOnly نگه دارید. به نشانی تمیزی هدایت کنید تا توکن از نوار نشانی بیرون برود.
-
توکن را با API به کار ببرید تا پس از
expires_inثانیه (۷ روز) منقضی شود. سپس کاربر را دوباره به نشانی مجوز بفرستید. کسی که پیشتر دسترسی انتشار داده «ورود به APP» و «شما قبلاً @myapp را مجاز کردهاید. دسترسی تازهای داده نمیشود.» را میبیند.
جریان کد
سرور شما یک کد میگیرد و آن را با یک توکن دسترسی و یک توکن تازهسازی مبادله میکند. بعدها میتواند بدون کاربر آنها را تازه کند. وقتی سرور شما مدت درازی بهجای کاربران عمل میکند، از آن استفاده کنید.
-
کاربر را با
scope=offlineبه نشانی مجوز بفرستید:https://hivesigner.com/oauth2/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=offline&state=STATEscope=posting&response_type=codeهمان کار را میکند. -
کاربر دسترسی انتشار را تأیید میکند. Hivesigner به نشانی بازگشت شما هدایت میکند:
REDIRECT_URI?code=CODE&state=STATE&username=USERNAME -
stateرا مقایسه کنید. سپس کد را بیدرنگ، از سرور خود، مبادله کنید.
کد را مبادله کنید
کد و کلید محرمانه کلاینت خود را در بدنه یک درخواست POST به /api/oauth2/token بفرستید:
curl -X POST https://hivesigner.com/api/oauth2/token \
-H 'Content-Type: application/json' \
-d '{"code": "CODE", "client_secret": "CLIENT_SECRET"}'
پاسخ:
{
"access_token": "ACCESS_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"expires_in": 604800,
"username": "alice"
}
همان فراخوانی در Node.js نسخه ۱۸ یا بالاتر:
const TOKEN_URL = 'https://hivesigner.com/api/oauth2/token';
export async function hivesignerTokens(grant) {
const res = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...grant,
client_secret: process.env.HIVESIGNER_CLIENT_SECRET,
}),
});
const data = await res.json();
if (!res.ok || data.error) {
throw new Error(`${data.error}: ${data.error_description}`);
}
return data; // { access_token, refresh_token, expires_in, username }
}
// On your callback, after checking state:
const tokens = await hivesignerTokens({ code: req.query.code });
- کد و کلید محرمانه را در بدنه درخواست بگذارید، هرگز در نشانی.
- با این درخواست هیچ سرایند
Authorizationنفرستید. - از
usernameهمین پاسخ استفاده کنید. از کدی میآید که کاربر امضا کرده است. - توکن دسترسی و توکن تازهسازی را روی سرور خود نگه دارید.
تازهسازی
وقتی توکن دسترسی منقضی شد، توکن تازهسازی را با کلید محرمانه کلاینت خود به همان نقطه بفرستید:
curl -X POST https://hivesigner.com/api/oauth2/token \
-H 'Content-Type: application/json' \
-d '{"refresh_token": "REFRESH_TOKEN", "client_secret": "CLIENT_SECRET"}'
const renewed = await hivesignerTokens({ refresh_token: stored.refresh_token });
پاسخ همان شکل را دارد، با یک توکن دسترسی تازه و یک توکن تازهسازی تازه. هر دو را بهجای قبلیها ذخیره کنید.
درخواست را با state محافظت کنید
بدون state، سایت دیگری میتواند کاربر شما را با توکن یا کدی از انتخاب خودش به نشانی بازگشت شما بفرستد. آنگاه برنامه شما کاربر را به حساب شخص دیگری وارد میکند. state هر بازگشت را به مرورگری که ورود را آغاز کرده گره میزند.
- برای هر ورود یک مقدار تصادفی بسازید، دستکم ۱۶ بایت تصادفی. شانزدهشانزدهی آن را از نویسههایی که به رمزگذاری نیاز دارند دور نگه میدارد.
- آن را جایی نگه دارید که تنها همین مرورگر بتواند دوباره ارائهاش کند: نشست سرور شما، یا یک کوکی کوتاهعمر httpOnly و Secure با
SameSite=Lax. - آن را بهعنوان
stateدر نشانی مجوز بفرستید. - در نشانی بازگشت، پارامتر
stateرا با مقدار ذخیرهشده مقایسه کنید. اگر نبود یا فرق داشت، بایستید: نه توکن را به کار ببرید نه کد را. - مقدار ذخیرهشده را پاک کنید تا هر کدام یک بار کار کند.
app.get('/auth/callback', async (req, res) => {
const expected = req.session.hivesignerState;
delete req.session.hivesignerState;
if (!expected || req.query.state !== expected) {
return res.status(400).send('This sign-in has expired. Please try again.');
}
// Token flow: req.query.access_token. Code flow: req.query.code.
});
Hivesigner همان مقدار state را که گرفته بازمیگرداند. مقدار تهی را کنار میگذارد.
کاربر چه میبیند
صفحه رضایت تصویر و نام برنامه شما، «حساب Hive @myapp» و «شما را به HOST میفرستد» را نشان میدهد، که HOST از نشانی بازگشت شما گرفته میشود. سپس:
- نخستین درخواست انتشار. عنوان میگوید «APP درخواست دسترسی به حساب شما را دارد.». کارت دامنه فهرست میکند که برنامه شما چه خواهد توانست بکند. آگهیای میگوید «مجوز برای نخستین بار: این کار @myapp را روی زنجیره به اختیار انتشار شما اضافه میکند و یک بار به کلید فعال شما نیاز دارد. آن حساب تا زمانی که مجوزش را لغو نکنید، میتواند بهجای شما پست بگذارد.». دکمه میگوید مجاز کردن. وقتی دستگاه کاربر کلید فعالی برای آن حساب نداشته باشد، صفحه همانجا آن را میخواهد.
- ورود. برای
scope=login، یا برای دسترسی انتشاری که کاربر پیشتر داده است، عنوان میگوید «ورود به APP» و دکمه میگوید ورود. - حساب. «مجاز کردن بهعنوان» یا «ورود بهعنوان»، و پس از آن حساب انتخابشده. کاربر میتواند اینجا حساب را عوض کند.
- حساب قفلشده. بالای دکمه، فیلدی برای رمز عبور هست. یک کلیک قفل حساب را باز میکند و ادامه میدهد.
- نبود هیچ حسابی روی دستگاه. دکمه میگوید ادامه. فرم افزودن حساب را باز میکند و پس از آن به درخواست بازمیگردد.
پس از نخستین درخواست انتشار، Hivesigner پیش از هدایت صبر میکند تا اجازه تازه روی زنجیره دیده شود. این کار میتواند چند ثانیه طول بکشد. برای دیدن صفحه کامل از دید کاربر، ببینید ورود به برنامهها.
لغو و درخواستهای ردشده
- لغو. کاربر به فهرست حسابهای خود در Hivesigner میرود. چیزی به نشانی بازگشت شما فرستاده نمیشود: هیچ پارامتر خطایی وجود ندارد. دکمه ورود خود را در دسترس نگه دارید تا کاربر بتواند دوباره آغاز کند. منتظر بازگشتی نباشید.
- درخواستهای ردشده. نشانی بازگشت ثبتنشده،
client_idناشناس یا نبودredirect_uriدر Hivesigner خطایی را با دکمه گزارش این مشکل نشان میدهد. چیزی به نشانی بازگشت شما فرستاده نمیشود. ببینید کاربران هنگام بروز مشکل چه میبینند.
نشانی قدیمی درخواست ورود
Hivesigner هنوز نشانی قدیمیتر ورود را میپذیرد، که برای یکپارچهسازیهای قدیمی نگه داشته شده است. برای موارد تازه از /oauth2/authorize استفاده کنید.
https://hivesigner.com/login-request/CLIENT_ID?redirect_uri=REDIRECT_URI&scope=posting&state=STATE
همان صفحه رضایت را با همان بررسیهای نشانی بازگشت و همان هدایت باز میکند. اما پارامترهایش را جور دیگری میخواند:
scopeبرابرloginیاpostingاست. هر مقدار دیگر، یا نبود آن، یعنیlogin.offlineخوانده نمیشود. برای جریان کد،response_type=codeبیفزایید.accountخوانده نمیشود.
https://hivesigner.com/login?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI از همان قاعدهها پیروی میکند.