Farzaneh Parvar
Farzaneh Parvar
خواندن ۱۲ دقیقه·۴ سال پیش

با OAuth2 آشنا شوید. قسمت دوم

این مقاله قسمت دوم از سری مقالات آشنایی با OAuth2 است. بنابراین اگر اطلاعات اولیه درمورد OAuth2 ندارید و هنوز قسمت اول رو مطالعه نکردید، پیشنهاد میکنم از لینک زیر استفاده کنید.

با OAuth2 آشنا شوید. قسمت اول


در قسمت قبل درمورد روش هایی که قبل از معرفی OAuth استفاده میشد و مزایا و معایب هرکدوم به تفسیر صحبت کردیم و در انتها بهترین و آخرین روش یعنی OAuth2 رو کمی معرفی کردیم. در این مقاله قصد داریم بیشتر درمورد OAuth2، فرآیندها، کامپوننت ها و توکن های این پروتکل صحبت کنیم.

پروتکل OAuth2 چیست؟

پروتکل OAuth2 یک پروتکل امنیتی است که به عنوان Authorization Protocol هم معرفی میشه. هدف اصلی این استاندارد اینه که Resource Owner (کاربر) مجوزی برای دسترسی به یک سری منابع محدود (Protected Resource) به یک کلاینت اعطا کند.

با توجه به اینکه اساس این پروتکل اعطا کردن مجوز دسترسی به یک Client application است، این پروتکل رو با نام Delegation Protocol هم معرفی میکنند.

این نکته رو فراموش نکنید که کلاینت ها باید از قبل در Authorization Server ثبت نام کنند. (یعنی سایتی که ما در قسمت اول پیاده سازیش رو استارت زدیم ;) ابتدا باید در Authorization Server اینستاگرام ثبت نام کرده باشه و یک شناسه ای تحت عنوان client_id دریافت کنه.) اما این به این معنی نیست که کلاینت میتونه با داشتن client_id در سیستم Authorized بشه. درواقع این کاربر یا همون Resource Owner هست که یک کلاینت رو برای بخشی از Protected Resource های خودش Authorize میکنه.

به عبارت دیگه مجوز از طرف یک کاربر مشخص به یک کلاینت مشخص اعطا میشه. بنابراین زمانی که کلاینت درخواست دسترسی به منابع یک کاربر رو ارسال میکنه، کلاینت باید از قبل توسط همان کاربر Authorize شده باشه. (تصمیم گیرنده اصلی کاربر است)

این استاندارد از چندین کامپوننت اصلی تشکیل شده که ارتباط این کامپوننت ها با همدیگه منجر به ایجاد یک OAuth2 Transaction (فرآیند OAuth) میشه.

فرآیند OAuth2 رو به طور کلی به صورت زیر درنظر بگیرید:

  1. کاربر به کلاینت میگه که کلاینت میتونه یه سری فعالیت از طرف او انجام بده. (مثال: کاربر به سایت ما میگه که میتونه پست های اینستاگرامش رو واکشی کنه.)
  2. کلاینت این درخواست رو به Authorization Server ارسال میکنه. در این درخواست دو پارامتر مهم باید ارسال بشه. client_id که مشخص کننده معتبر بودن کلاینت و scope که تعیین کننده دسترسی های موردنیاز هست. (در این مورد در انتهای مقاله بیشتر توضیح داده میشه.)
  3. کامپوننت Authorization Server در ابتدا معتبر بودن کلاینت رو براساس client_id ارسال شده بررسی میکند. اگر کلاینت معتبر بود، فرآیند وارد مرحله بعدی میشه، درغیر این صورت درخواست کلاینت Failed میشه.
  4. در این مرحله Authorization Server از Resource Owner میپرسه که آیا مطمئنه که قصد داره این دسترسی ها رو به کلاینت اعطا کنه یا خیر؟
  5. اگر کاربر این رضایت نامه رو تایید کنه، Authorization Server یک توکن به نام Access Token میسازه و برای کلاینت ارسال میکنه.
  6. از این مرحله به بعد، هر زمان که کلاینت قصد داشت درخواستی به Protected Resource های کاربر ارسال کند، باید توکن رو در Body یا Header درخواست قرار بده.
به طور خلاصه OAuth2 در دو مرحله خلاصه میشه:
- چطور یک توکن رو از Authorization Server بگیریم؟
- چطور از توکن به دست آمده برای دسترسی به منابع Protected استفاده کنیم؟

نقش های OAuth2

همانطور که در قسمت قبل اشاره کردیم، چهار نقش اصلی در پروتکل OAuth2 وجود داره:

  • Clients
  • Resource Owners
  • Authorization Servers
  • Protected Resources

هر نقش وظایف متفاوتی رو برعهده داره، اما در نهایت تعامل این نقش ها با همدیگه باعث میشه که پروتکل OAuth2 کار کنه. در این قسمت قصد داریم جزئیات بیشتری از هرکدوم ارائه بدیم:

کلاینت یا Client

کلاینت یک اپلیکیشن موبایل یا وب است که قصد داره از طرف یک Resource Owner به یک Protected Resource دسترسی داشته باشه. کلاینت از پروتکل OAuth2 برای به دست آوردن این دسترسی استفاده میکنه.

کلاینت کمترین وظیفه رو در فرآیند OAuth2 برعهده داره. تنها کاری که یک کلاینت باید انجام بده ارسال درخواست برای گرفتن Access Token و سپس استفاده از این توکن در درخواست های Protected Resource های کاربر هست. درواقع کلاینت اصلا درجریان نحوه گرفتن مجوز از کاربر، تولید توکن و اعتبارسنجی آن نیست. کلاینت حتی نیازی نداره که درمورد محتوای توکن چیزی بدونه. میشه گفت کلاینت با Access Token مثل یه رشته ثابت برخورد میکنه که باید در تمام درخواست های Protected Resource ارسال بشه.

منابع محافظت شده یا Protected Resource

درمورد منابع در قسمت قبل توضیح مفصلی دادیم. مجددا این نکته را یادآوری می کنیم که Resource ها منابعی هستند که از طریق پروتکل HTTP دردسترس هستند. اما Protected Resource ها منابعی هستند که برای دسترسی به آنها نیاز به اعتبارسنجی داریم. در OAuth2 منظور از اعتبارسنجی همان Access Token هست. زمانی که کلاینت درخواستی رو به یک Protected Resource ارسال میکنه، اعتبار توکن با کمک Authorization Server بررسی میشه و اگه توکن معتبری همراه با درخواست فرستاده شده باشه، Protected Resource اطلاعات موردنیاز کلاینت رو پردازش و ارسال میکند.

کاربر یا Resource Owner

کاربر همان موجودیتی است که به یک Protected Resource دسترسی داره و قصد داره این دسترسی رو به یک کلاینت اعطا کنه. در بیشتر مواقع (همچنین در سناریوی ما) کاربر یک انسان است، اما این رو هم درنظر بگیرید که Resource Owner میتواند یک کلاینت دیگر باشد.

کاربر با دو نقش Client و Authorization Server در ارتباط است. در وهله اول کاربر به کلاینت میگه که یک سری از کنترل ها رو میخواد به اون بسپاره (دسترسی به Protected Resource) و بعد به Authorization Server اطمینان میده که با این درخواست دسترسی کلاینت موافق هست. (این دریافت مجوز عمدتا از طریق یک صفحه وب انجام میشه که در زیر میتونید نمونه اشو ببینید.)

Consent page of Instagram
Consent page of Instagram

اگر به تصویر دقت کنید در ابتدا نوشته شده که کلاینت My Site Feed قصد گرفتن مجوزهای زیر رو داره و در ادامه مجوزهای موردنیاز لیست شده. به این صفحه اصطلاحا صفحه رضایت نامه کاربر هم گفته میشه. Resource Owner رضایت خودش رو از این اعطای مجوز اعلام میکنه.

همانطور که در ابتدای مقاله هم گفته شد در OAuth2 تصمیم گیرنده اصلی Resource Owner است.

ا Authorization Server

اصلی ترین نقش در پروتکل OAuth2 متعلق به Authorization Server است. وظایف این کامپوننت به شرح زیر است:

  • شناسایی کردن کاربر (User Authentication)
  • شناسایی کردن کلاینت با استفاده از client_id و سایر مشخصات (Client Authentication)
  • فراهم کردن Access Delegation (یعنی کلاینت توسط Resource Owner برای یک سری دسترسی های مشخص Authorize بشه.)
  • تولید توکن
  • اعتبارسنجی توکن در هر درخواست

موارد ذکر شده اصلی ترین وظایف Authorization Server است و بسته به سیاست های کاری شرکت میتواند گسترده تر هم شود.


توکن ها در OAuth2

تا اینجا متوجه شدیم که توکن نقش اصلی رو در اعتبارسنجی برعهده داره، درواقع تمام فرآیند OAuth2 در دو مرحله زیر در ارتباط مستقیم با توکن است:

  1. کلاینت بعد از اعتبارسنجی، Access Token رو از Authorization Server دریافت میکند.
  2. کلاینت در هر درخواست خود به Protected Resource توکن به دست آورده را ارسال میکند.

اما Access Token تنها توکن موجود در OAuth2 نیست. در این بخش بیشتر در این خصوص صحبت خواهیم کرد.

توکن Access

توکن Access توسط Authorization Server برای کلاینت صادر میشه و نشان دهنده دسترسی هایی است که از طرف Resource Owner به کلاینت واگذار شده.

پروتکل OAuth فرمتی برای توکن ها تعیین نکرده، بنابرین این وظیفه OAuth Provider (مثل اینستاگرام) است که براساس سیستم خود، ساختار و محتوای توکن رو تعیین کند.

همانطور که قبلا هم اشاره شد، کلاینت چیزی درمورد محتوا و ساختار توکن ها نمیداند، اصلا نیازی به دانستن آن ندارد. تنها کاری که کلاینت با توکن دارد، درخواست دریافت توکن و ارسال توکن در هر درخواست به Protected Resource است.

اما از آنجایی که Authorization Server صادر کننده توکن و Protected Resource دریافت کننده توکن است، باید مشترکا درمورد ساختار، محتوا و نحوه پارس کردن آن اطلاعات کافی داشته باشند.

توکن Refresh

توکنی که کلاینت به نام Access Token دریافت میکنه، بعد از مدتی منقضی میشه، یعنی اگه کلاینت اون Access Token رو در ریکویست به Protected Resource ارسال کنه، با این ارور مواجه میشه که توکن فرستاده شده معتبر نیست و باید توکن جدید گرفته بشه. پس ما مجددا باید فرآیند OAuth رو تکرار کنیم که با فرستادن کاربر به Authorization Server و تایید کردن مجوزها توسط Resource Owner شروع میشه.

در اکثر OAuth2 Provider ها میزان اعتبار Access Token یک ساعته، یعنی کلاینت هر یک ساعت یکبار باید کاربر رو به Authorization Server بفرسته تا بتونه Access Token جدید بگیره. کاملا مشخصه که این رفت و آمدها از حوصله کاربر خارجه. روش جایگزین استفاده از Refresh Token است.

توکن Refresh مانند Access Token توسط Authorization Server برای کلاینت صادر میشه. مشخصات اصلی Refresh Token کاملا شبیه Access Token است.

  • کلاینت از ساختار و محتوای Refresh Token اطلاعی ندارد.
  • توکن Refresh توسط Authorization Server در درخواست اولیه همراه با Access Token صادر و برای کلاینت ارسال میشه.
  • پروتکل OAuth تعیین کننده ساختار و محتوای Refresh Token نیست و این وظیفه به Provider محول شده.

تنها تفاوت Refresh Token با Access Token در این است که Refresh Token برای Protected Resource ارسال نمی شود. بلکه هر زمان که اعتبار Access Token از بین رفت (مثلا هر یک ساعت یکبار) کلاینت درخواست دریافت توکن جدید رو به Authorization Server ارسال میکنه و این درخواست باید شامل Refresh Token معتبر باشه.

مدت اعتبار Refresh Token هم مانند Access Token در میان Provider ها مشترک نیست. اما میانگین میتوان 30 روز را درنظر گرفت.

درنتیجه هر زمان که اعتبار Access Token تمام شد، کلاینت باید درخواستی برای گرفتن توکن جدید ارسال کند و این فرآیند بدون دخالت Resource Owner انجام میشه. البته این به شرطی است که کلاینت Refresh Token معتبر داشته باشد. اگر اعتبار Refresh Token هم تمام شده باشد، چاره ای به جز تکرار کردن فرآیند اولیه OAuth2 نداریم.

نمودار زیر رو درنظر بگیرید:

نحوه استفاده از Refresh Token
نحوه استفاده از Refresh Token


  1. کلاینت درخواست دسترسی به یک Protected Resource رو ارسال میکنه. همانطور که می دونید باید Access Token رو در درخواست ارسال کنید.
  2. کامپوننت Protected Resource با همکاری Authorization Server متوجه نامعتبر بودن Access Token میشه. درنتیجه در جواب ارور برمیگردونه.
  3. کلاینت درخواستی برای گرفتن توکن جدید به Authorization Server ارسال میکنه. همراه این درخواست باید Refresh Token ارسال بشه.
  4. کامپوننت Authorization Server اعتبار Refresh Token رو بررسی میکنه و درصورت معتبر بودن دو توکن جدید Refresh Token و Access Token صادر و برای کلاینت ارسال میکنه.
  5. از این مرحله به بعد کلاینت تمامی درخواست های Protected Resource رو با Access Token جدید ارسال میکنه.
  6. هر زمان که مجددا اعتبار Access Token تمام بشه، این مراحل تکرار میشه.

دامنه دسترسی یا Scopes

دامنه دسترسی (Scope) را همان Permission در یک سیستم ACL درنظر بگیرید. زمانی که کلاینت درخواست Authorization رو به Authorization Server ارسال میکنه، Scope های موردنیاز رو تعیین میکنه. Authorization Server این Scope های درخواستی را به کاربر نمایش میده و به ازای آن ها از کاربر میخواد که کلاینت را Authorize کند.

پروتکل OAuth تنها مفهوم و یک سری از شرایط تعریف Scope را تعیین کرده است و وظیفه تعریف کردن Scope ها به عهده Protected Resource هست. برای مثال اینستاگرام می تواند Scope های زیر را برای دسترسی به API خود تعریف کند.

  • دامنه read_profile: دسترسی به خواندن اطلاعات پروفایل کاربر
  • دامنه edit_profile: دسترسی به ویرایش اطلاعات پروفایل کاربر
  • دامنه public_resources: دسترسی به پیج های پاپلیک کاربر
  • دامنه read_comments: دسترسی به خواندن کامنت های کاربر
  • و ...

فرض کنید کلاینتی با دو اسکوپ read_profile و public_resources درخواستی برای گرفتن Access Token ارسال کرده است. در این صورت کلاینت تنها میتواند به این دو بخش از API دسترسی داشته باشد. برای مثال اگر کلاینت درخواستی برای ویرایش پروفایل کاربر ارسال کند، Protected Resource پس از پارس کردن Access Token و بررسی Scope های آن متوجه می شود که کلاینت مجوز دسترسی به این بخش را ندارد در نتیجه پاسخ 403 برمیگرداند.


منبع:

OAuth2 in Action 1st edition. Manning Publications Co.

oauthoauth2احراز هویتauthenticationAuthorization
شاید از این پست‌ها خوشتان بیاید