व्यवहार में OAuth। लोकप्रिय सामाजिक नेटवर्क के माध्यम से साइट उपयोगकर्ताओं का प्रमाणीकरण और प्राधिकरण

मुझे लगता है कि यह मुझे अकेला नहीं है जो उन संसाधनों से बेहद थक गया है जिन्हें हर अवसर पर और बिना पंजीकरण की आवश्यकता होती है। एक अनिवार्य कैप्चा के साथ, जो ई-मेल द्वारा पुष्टि के साथ केवल पांचवीं बार सही ढंग से दर्ज किया जाएगा, जो निश्चित रूप से स्पैम में गिर जाएगा, और वह केवल एक दिन के बाद। हर बार एक नई लॉगिन-पासवर्ड जोड़ी को भूल जाना, सभी साइटों पर एक ही चीज दर्ज करना सुरक्षित नहीं है। कुछ स्थानों पर "क्वर्टी: क्वर्टी" या "लॉगिन: पासवर्ड" जैसे जोड़े लुढ़के हैं, लेकिन, अफसोस, हर जगह नहीं। इससे थक गए। यह गणना नहीं करता है कि मैं कितनी बार शिलालेख देख रहा हूं, "केवल एक पंजीकृत उपयोगकर्ता **** है," बस कुटिल और टैब को बंद कर दिया ताकि मैं इस साइट पर फिर कभी न जाऊं। क्या संसाधन प्रशासक स्वयं इसे नहीं समझते हैं? लेकिन OAuth तकनीक पहले से ही 6 साल पुरानी है, और 90% इंटरनेट दर्शकों के पास कम से कम एक संसाधन पर एक खाता है जो AAuth का समर्थन करता है। तो हर संसाधन पर "लॉगिन थ्रू" बटन क्यों उपलब्ध नहीं है? मैंने अपनी साइट पर सर्वेक्षण स्थापित किया छवि उन। थोड़ा वोट किया (मेरे सभी उपयोगकर्ताओं के पास अपनी पंजीकरण साइट नहीं है), लेकिन इस लेख को लिखने के लिए विचार प्राप्त करने के लिए पर्याप्त है, इस उम्मीद में कि प्राधिकरण के लिए OAuth का उपयोग करके अधिक साइटें होंगी। क्योंकि:

OAuth क्यों है और OpenID नहीं है?

क्योंकि ओपनआईडी उन उद्देश्यों के लिए व्यावहारिक रूप से बेकार है जिनके लिए यह घोषित किया गया है। यह विशुद्ध रूप से मेरी राय है, लेकिन यह खाली जगह पर भरोसा नहीं करता है।
सबसे पहले, OpenIDs का उपयोग मुख्य रूप से geeks द्वारा किया जाता है, जिनके इंटरनेट पर प्रतिशत इतना अधिक नहीं है कि उनके लिए साइटों को फिर से बनाया जाए (कुछ अपवादों के साथ, निश्चित रूप से :)) ऐसा क्यों है? क्योंकि OpenID खाता प्राप्त करने के लिए, आपको - प्राप्त करने की आवश्यकता है। ओपनआईडी सर्वर पर जाएं और एक निश्चित, बल्कि अजेय, चरित्र सेट प्राप्त करने के लिए कुछ क्रियाएं करें। जो, जटिलता के बावजूद (एक साधारण उपयोगकर्ता के लिए), आपको एक परिचित पोर्टोग्राम देखने और भूलने की जरूरत नहीं है छवि । खैर, यह आकस्मिक उपयोगकर्ता क्या करेगा? और OAuth के साथ, सब कुछ बहुत सरल है - एक व्यक्ति पंजीकृत उपयोगकर्ता के अधिकारों के साथ साइट पर पहले से ही "लॉग इन वीकेन्टेक्ट" बटन, क्लिक, और ... देखता है। "सरल बनो," क्लासिक ने कहा, और लोग आपके लिए पहुंचेंगे। जैसे उसने पानी में देखा।
दूसरे, OAuth विशेषताएँ प्रमाणीकरण और प्राधिकरण तक सीमित होने से बहुत दूर हैं। प्राधिकरण प्रक्रिया के दौरान एक टोकन प्राप्त करने के बाद, इसका उपयोग सोशल मीडिया क्षमताओं को आपके संसाधन में आगे बढ़ाने के लिए किया जा सकता है - पोस्टिंग / लेखन पोस्ट, मित्र और दीवार तक पहुंच, और बहुत कुछ।
तीसरा, OpenID सक्रिय रूप से स्पैमर्स और हैकर्स द्वारा उपयोग किया जाता है। अक्सर, एक संसाधन पर OpenID प्रमाणीकरण का कार्यान्वयन इसकी ज्ञात कमजोरियों पर विशेष ध्यान दिए बिना किया जाता है - केवल OpenID प्रदाता पर प्रोटोकॉल के विवरण से या किसी अज्ञात द्वारा लिखे गए पुस्तकालय की मदद से। उदाहरण के लिए, कई साइटों को ओपनआईडी इनपुट से कैप्चा इनपुट की आवश्यकता नहीं होती है। और कुछ भी हमलावर को अपने ओपनआईडी सर्वर को लेने से रोकता है, जो किसी भी पहचानकर्ता की पुष्टि करेगा और स्वचालित रूप से पहचानकर्ता के साथ एक विश्वसनीय साइट को स्पैम करना शुरू कर देगा। इसके अलावा, OpenID प्रमाणीकरण, संक्षेप में, ग्राहक को कोई गारंटी नहीं देता है। यह केवल इस बात की पुष्टि करता है कि अनुरोधित उपयोगकर्ता वास्तव में OpenID सर्वरों में से एक पर पंजीकृत है - और यह सब। उपयोगकर्ता (ईमेल, नाम, आयु) के बारे में अतिरिक्त जानकारी प्राप्त करने के लिए तंत्र उपलब्ध हैं, लेकिन कुछ समर्थित हैं। आप निश्चित रूप से, OpenID के विचारों का उल्लंघन करते हुए, पहचानकर्ता का विश्लेषण कर सकते हैं और केवल कुछ OpenID प्रदाताओं पर भरोसा कर सकते हैं (उदाहरण के लिए, समान सामाजिक नेटवर्क)। लेकिन यह समझ में आता है अगर उनमें से लगभग सभी (एलजे के अपवाद के साथ, लेकिन वह ओपिड द्वारा उपयोगकर्ता के बारे में कुछ भी नहीं बताएंगे) OAuth का समर्थन करते हैं, जो आपको बहुत अधिक जानकारी प्राप्त करने की अनुमति देता है? इसलिए मैंने अपनी सभी साइटों से OpenID समर्थन हटा दिया।

OAuth और विजेट के माध्यम से लॉगिन क्यों नहीं है?

कोई बात नहीं। यदि आप विजेट की कार्यक्षमता, डिजाइन और सुरक्षा स्तर से संतुष्ट हैं - तो इसे कोड में चिपका देना वास्तव में बहुत आसान है - आप आगे नहीं पढ़ सकते हैं।

यह कैसे काम करता है?

यदि किसी को सभी विवरणों में रुचि है, तो ऊपर दिए गए लिंक देखें। संक्षेप में:
  1. सेवा प्रदाता XXX पर जाएं, वहां अपनी साइट पंजीकृत करें, क्लाइंट कोड और गुप्त कोड प्राप्त करें।
  2. अपनी साइट के एक बटन पर क्लिक करें "XXX के माध्यम से लॉग इन करें", आप XXX सर्वर के साथ अनुरोधों का आदान-प्रदान करते हैं, उपयोगकर्ता को पासवर्ड दर्ज करने के लिए XXX पर पुनर्निर्देशित करते हैं, अपनी वेबसाइट पर डेटा के हस्तांतरण की पुष्टि करते हैं और एक टोकन प्राप्त करते हैं जिसके साथ आप XXX सर्वर से अतिरिक्त जानकारी का अनुरोध कर सकते हैं। । एक सेवा प्रदाता पर OAuth के कार्यान्वयन पर बारीकियों पर निर्भर करता है - एक समर्थित प्रोटोकॉल संस्करण, समर्थित स्ट्रीम आदि।
  3. प्राप्त टोकन का उपयोग करते हुए, नाम, ईमेल, जन्म तिथि, अवतार और अन्य जानकारी जो आमतौर पर पंजीकरण के दौरान आवश्यक होती है, XXX सर्वर से प्राप्त की जाती है। उसके बाद, आप नए उपयोगकर्ता को जोड़ने के लिए मानक फ़ंक्शन को कॉल कर सकते हैं।


क्यों कच्चे HTTP और नहीं OAuth पुस्तकालय का उपयोग स्निपेट्स कोड?

चूँकि मुझे इस आदेश से पीड़ा हुई थी, इसलिए यह बहुत ही कच्चा HTTP एक या किसी अन्य पुस्तकालय के उपयोग को दर्शाने वाले कोड के टुकड़ों से खींच रहा था। प्रत्येक सर्वर पर विशिष्ट OAuth कार्यान्वयन की अपनी सूक्ष्मताएं हैं, इससे पहले कि सबसे लचीली लाइब्रेरी भी बचा सकती है। इसके अलावा, कई वेब भाषाएं, पुस्तकालय हैं - और भी, सब कुछ के लिए उदाहरण देना केवल अवास्तविक है। और कच्चे HTTP (दिमाग के साथ) किसी भी पुस्तकालय का उपयोग करने के लिए पर्याप्त है। आप इसके विपरीत नहीं कह सकते।

व्यावहारिक कार्यान्वयन दिशानिर्देश

बेशक, सबसे पहले, आपको सोशल नेटवर्क पर पंजीकरण करने की आवश्यकता है, खाते को सक्रिय करें, और इसी तरह। अपना समय ले लो। कुछ सर्वर तुरंत नए पंजीकृत OAuth क्लाइंट से अनुरोधों को सही ढंग से नहीं संभालते हैं। यहां मैंने केवल सफल थ्रेड्स को चित्रित किया, त्रुटि से निपटने के बारे में भूलना इसके लायक नहीं है। मैंने सुरक्षा पहलुओं पर भी लगभग ध्यान नहीं दिया - यह एक अलग लेख का विषय है। कम से कम, जहां भी आप प्रत्येक उपयोगकर्ता के लिए कॉलबैक-यूआरएल के लिए एक अनूठा पैरामीटर पास कर सकते हैं, यह करने योग्य है (मुख्य कॉलबैक पता अपरिवर्तित रहना चाहिए, और केवल पैरामीटर को बदलना चाहिए, अन्यथा सर्वर अनुरोध को याद नहीं करेगा। इस पर विशेष ध्यान दें यदि आपको mod_rewrite का उपयोग करना चाहिए), साथ ही कॉलबैक स्क्रिप्ट (जहां यह पैरामीटर समर्थित है) में अतिरिक्त डेटा स्थानांतरित करने के लिए राज्य पैरामीटर का उपयोग करें। मैंने फिलहाल यह सब छोड़ दिया है।

छवि VKontakte
1. यहाँ आओ। प्रकार - "वेबसाइट"। आधार डोमेन और वेबसाइट का पता दर्ज करें। सेटिंग्स पृष्ठ पर, हमें client_id (एप्लिकेशन आईडी) और secret_key (सुरक्षित कुंजी) मिलता है। छवि 2. हम कोड को एक बटन की तरह चिपकाते हैं
<a href="http://oauth.vk.com/authorize?client_id={client_id}&redirect_uri=mysite.com/vklogin&response_type=code" title="  ">  </a>
response_type=code, token? response_type=token. vklogin? , , .
3. vklogin?
3.1. vklogin get- ( ) .
http://mysite.com/vklogin?code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a
http://mysite.com/vklogin?error=invalid_request&error_description=Invalid+display+parameter
, code,
3.2. https- ( POST, GET. , ) :
GET https://oauth.vk.com/access_token?client_id={client_id}&client_secret={secret_key}& code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a//
3.3. . , 200 OK . JSON, access_token user_id. ( ) GET — users.get API :
GET https://api.vk.com/method/users.get?uids={user_id}&fields=uid,first_name,last_name,nickname,screen_name,sex,bdate,city,country,timezone,photo&access_token={access_token}
3.4. ( ) - JSON . . — utf8, — , .
, , . API .

image
1. . OAuth . -. , , . , . «», ...
2. , , .image
. «» , client_id(Application ID), public_key( ) secret_key( )
3. :
<a href="http://www.odnoklassniki.ru/oauth/authorize?client_id={client_id}&response_type=code&redirect_uri=http://mysite.com/oklogin" title="">  </a>
4. oklogin
3.1. code.
3.2. POST :
http://api.odnoklassniki.ru/oauth/token.do
:
code={code}&redirect_uri=http://mysite.com/oklogin&grant_type=authorization_code&client_id={client_id}&client_secret={secret_key}
3.3. JSON , access_token. GET-:
GET http://api.odnoklassniki.ru/fb.do?method=users.getCurrentUser&access_token={access_token}&application_key={public_key}&sig={sign}
sign — md5-
sign=hex_md5('application_key={public_key}method=users.getCurrentUser'+hex_md5({access_token}+{secret_key}))
-, .
3.4. JSON- , , , . — utf8;
users.getCurrentUser . API . , , .

imageFacebook
1. « ». App Domains () (). «Website with Facebook Login» url . client_id (App ID) secret_key (App Secret).image «Auth Dialog» «Authenticated Referrals» «code» «Auth Token Parameter». image
2. :
https://www.facebook.com/dialog/oauth?client_id={client_id}&redirect_uri=mysite.com/fblogin&response_type=code
3.fblogin.
3.1. code.
3.2. GET
GET https://graph.facebook.com/oauth/access_token?client_id={client_id}&redirect_uri=http://mysite.com/fblogin&client_secret={client_secret}&code={code}
3.3. (param1=value1¶m2=value2). access_token, GET-:
GET https://graph.facebook.com/me?access_token={access_token}
3.4. JSON- , , , . — NFC ( \u0410\u0401\u0419)
API ( ) .

imageTwitter
1. . , , -. image «Create my access token».image

, . . ??? twitter - OAuth-. , ( Net::OAuth ) .

1. OAuth 1.0 . « Twitter» , POST-
https://api.twitter.com/oauth/request_token
:
Authorization:OAuth oauth_callback=«http%3A%2F%2Fmysite.com%2Ftwlogin», oauth_consumer_key="{consumer_key}", oauth_nonce="{nonce}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_version=«1.0»
oauth_callback — escape-uri - ;
consumer_key ;
nonce — base64 , , , 32, , ;
time — unix- ( , , «» , « »);
sign — HMAC-SHA1 .
nonce — .
1.1. . , escape-, '&'. :
{_}&{escape-uri }&{escape- }
, escape- . , , :
str='POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3D{http%253A%252F%252Fmysite.com%252Ftwlogin}%26oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 srting}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_version%3D1.0'
1.2. , hmac_sha1 (, , ) 64. - :
str1=hmac_sha1(str,Consumer_secret+'&'+OAuth_token_secret,64).
OAuth token secret- , , Consumer secret '&'. ( ) base_64 , escape-. . .
2. , oauth_token=XXXXX.
https://api.twitter.com/oauth/authenticate?oauth_token=XXXXX
3. twlogin, :
3.1. oauth_token oauth_verifier ( )
3.2. POST-
https://api.twitter.com/oauth/access_token
Authorization:OAuth oauth_consumer_key="{consumer_key}", oauth_nonce="{random base64 string}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_token="{oauth_token}", oauth_version=«1.0»'
, :
oauth_verifier={oauth_verifier}
oauth_token oauth_verifier , , sign
str='POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Faccess_token&oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 string}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_token%3D{oauth_token}%26oauth_verifier%3D{oauth_verifier}%26oauth_version%3D1.0';
3.3. , . GET-
GET https://api.twitter.com/1/users/lookup.json?user_id={user_id}
Authorization:OAuth oauth_consumer_key="{consumer_key}", oauth_nonce="{random base64 string}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_token="{oauth_token}", oauth_version=«1.0»'
user_id oauth_token ,
str='GET&https%3A%2F%2Fapi.twitter.com%2F1%2Flookup.json&oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 string}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_token%3D{oauth_token}%26oauth_version%3D1.0%26user_id%3D{user_id}'
, , oauth_token_secret:
str1=hmac_sha1(str,Consumer_secret+'&'+OAuth_token_secret,64)
3.4. JSON- , , . API .

imageMail.ru ()
1. . , receiver.html, . receiver.html — , JS API, , , , receiver.html , . client_id (ID) secret_key ( ).image2. :
<a href="https://connect.mail.ru/oauth/authorize?client_id={client_id}&response_type=code&redirect_uri=http%3A%2F%2Fmysite.com%2Fmmlogin">  MailRu</a>
3. mmlogin
3.1. code.
3.2. POST :
https://connect.mail.ru/oauth/token
:
client_id={client_id}&client_secret={secret_key}&grant_type=authorization_code&code={code}&redirect_uri=http://mysite.com/mmlogin
3.3. JSON , access_token. GET-:
GET http://www.appsmail.ru/platform/api?method=users.getInfo&secure=1&app_id={client_id}&session_key={access_token}&sig={sign}
sign — md5-
sign=hex_md5('app_id={client_id}method=users.getInfosecure=1session_key={access_token}{secret_key}')
hex string.
3.4. JSON- , , , . — utf8;
API ( ) .

image
1. . .. . image
client_id(Id ) secret_key( ).image
2. :
<a href="https://oauth.yandex.ru/authorize?response_type=code&client_id={client_id}" title="">  </a>
3. yalogin
3.1. code.
3.2. POST :
https://oauth.yandex.ru/token
:
grant_type=authorization_code&code={code}&client_id={client_id}&client_secret={secret_key}
3.3. JSON , access_token. GET-:
GET https://login.yandex.ru/info?format=json&oauth_token={access_token}
3.4. JSON- , , email, . (, . . . — c, — « » .) — NFC-. , json- . , ,
email : xxx@ttt.com
. , RFC JSON , — - .
API yandex.login .

imageGoogle
1. . . API access «Create an OAuth2 client ID».image client_id(Client ID) secret_key(Client Secret).image
2. :
<a href="https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Fmysite.com%2Fgglogin&response_type=code&client_id={client_id}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile" title="  Google">  Google</a>
3. gglogin
3.1. code.
3.2. POST :
https://accounts.google.com/o/oauth2/token
:
code={code}&client_id={client_id}&client_secret={secret_key}&redirect_uri=http://mysite.com/gglogin&grant_type=authorization_code
Content-type:application/x-www-form-urlencoded
3.3. JSON , access_token. GET-:
GET https://www.googleapis.com/oauth2/v1/userinfo?access_token={access_token}
3.4. JSON- .
API - .

. , .
, , OAuth. , , .
perl, , OAuth — . — .

Source: https://habr.com/ru/post/In145988/


All Articles