oauth0 oauth2
A common complaint about OAuth is that it is very difficult to understand, but perhaps some of that confusion is because of an expectation that the abstraction provided by a third-party library will erase the need to understand the steps of an OAuth transaction – it does not. This two-part article demonstrates how how OAuth v1 works by explaining the process of connecting a PHP application to the Twitter API using only a few built-in functions to post a message to a user’s Twitter stream.
关于OAuth的一个普遍抱怨是很难理解,但其中的一些困惑可能是因为期望第三方库提供的抽象将消除对OAuth事务处理步骤的理解。不。 这篇由两部分组成的文章通过说明仅使用一些内置函数将消息发布到用户Twitter流的将PHP应用程序连接到Twitter API的过程,来演示OAuth v1的工作方式。
The example code provided in this article is intended for educational purposes only. It lacks much practical use and error handling, Any real development should take advantage of an existing OAuth library, but after reading this article you’ll have a better understanding of how OAuth works and will be better equipped to troubleshoot any problems that may arise.
本文提供的示例代码仅用于教育目的。 它缺乏实际的使用和错误处理,任何实际的开发都应利用现有的OAuth库,但是阅读本文后,您将对OAuth的工作方式有更好的了解,并且可以更好地解决可能出现的任何问题。
Posting to Twitter on behalf of a user without asking for a username and password combination every time requires a sort of “valet key”… this key is OAuth. In OAuth terms, your client application is called the consumer, the user is called the resource owner, and Twitter is the server or service provider.
每次不代表用户名和密码组合就代表用户发布到Twitter都需要一种“代用密钥”…此密钥是OAuth。 用OAuth术语来说,您的客户端应用程序称为使用者 ,用户称为资源所有者 ,Twitter是服务器或服务提供商 。
Before Twitter will accept a post from your application, you need to obtain your own client credentials: the Consumer Key and Consumer Secret. Twitter, like most services that provide a public API, will grant you a key and secret after completing a registration form (available at dev.twitter.com/apps). With Twitter, you need to supply some information that will identify your application to the user during the authorization process, specifically its name, description, and website URL. You also need to enter a Callback URL, which I’ll explain later.
在Twitter接受您应用程序中的帖子之前,您需要获取自己的客户凭证: Consumer Key和Consumer Secret 。 像大多数提供公共API的服务一样,Twitter将在完成注册表格(可在dev.twitter.com/apps上 )后为您提供密钥和机密。 使用Twitter,您需要提供一些信息,以在授权过程中向用户标识您的应用程序,特别是其名称,描述和网站URL。 您还需要输入一个回调URL,我将在后面解释。
Once you have submitted the Create an Application form, you will be taken to a Details page for your new application. Scroll down to find your Consumer Key and Secret. You’ll need these along with the handful of endpoint URLs that are listed. Notice the application is granted Read Only access by default; since it will be posting tweets, you need to click the Settings tab and change the access to “Read and Write”.
提交“创建应用程序”表单后,将转到新应用程序的“详细信息”页面。 向下滚动以找到您的使用者密钥和秘密。 您将需要这些以及列出的少数端点URL。 注意,默认情况下,该应用程序被授予只读访问权限; 因为它将发布推文,所以您需要单击“设置”选项卡并将访问权限更改为“读取和写入”。
The Consumer Key and Consumer Secret allow your application to talk to the Twitter API, but those alone won’t let it post tweets on another user’s behalf. You need access credentials: an Access Token and Access Secret. To obtain these through a request to the Service Provider (Twitter) in a short conversation using the consumer credentials involving Twitter and the end-user. Obtaining the access credentials can be fairly painful, but luckily you only need to do this once per user. You can save the credentials indefinitely for later use and not require the user to reauthorize your application. The conversation requesting the access credentials requires its own set of credentials: the Request Token and Request Secret.
使用者密钥和使用者密钥允许您的应用程序与Twitter API进行通信,但是仅凭这些密钥,就不能让它代表另一个用户发布推文。 您需要访问凭证: 访问令牌和访问密钥 。 通过使用涉及Twitter和最终用户的消费者凭证在短时间内通过向服务提供商(Twitter)的请求获得这些信息。 获取访问凭据可能会非常痛苦,但是幸运的是,每个用户只需执行一次。 您可以无限期保存凭据以供以后使用,而无需用户重新授权您的应用程序。 请求访问凭证的会话需要其自己的凭证集: 请求令牌和请求机密 。
The authorization process typically starts by directing the user to an Authorize Twitter page. This is a page you create that initiates the request for a Request Token from Twitter and begins the OAuth authorization process. It must generate a URL used to grab the Request Credentials, and once you have the credentials you can redirect the user to Twitter to grant the application permission to post.
授权过程通常从将用户定向到“授权Twitter”页面开始。 这是您创建的页面,该页面从Twitter发起对请求令牌的请求,并开始OAuth授权过程。 它必须生成一个用于获取请求凭证的URL,一旦获得凭证,就可以将用户重定向到Twitter,以授予应用程序发布权限。
Requesting the Request Credentials requires a signed request, which means you need to send an OAuth signature along with other important parameters in the request. The signature is a base64-encoded hashed list of the request parameters. In Twitter’s case, the hashing algorithm is HMAC-SHA1. The signing process prevents anyone else from posing as your application with your credentials even though the Consumer Key is transmitted in plain text. The signature can only be reproduced by you (the Consumer) and the server (Twitter) because you two are the only entities that should know the Consumer Secret that hashes the signature.
请求请求凭据需要经过签名的请求,这意味着您需要发送OAuth签名以及请求中的其他重要参数。 签名是请求参数的base64编码的哈希列表。 在Twitter的情况下,哈希算法为HMAC-SHA1。 即使消费者密钥以纯文本格式传输,签名过程也可以防止其他人使用您的凭据伪装成您的应用程序。 签名只能由您(消费者)和服务器(Twitter)复制,因为你们两个是唯一应该知道散列签名的消费者秘密的实体。
Lets build a string the signature is based on:
让我们构建一个基于签名的字符串:
<?php
$requestTokenUrl = "http://api.twitter.com/oauth/request_token";
$authorizeUrl = "http://api.twitter.com/oauth/authorize";
$oauthTimestamp = time();
$nonce = md5(mt_rand());
$oauthSignatureMethod = "HMAC-SHA1";
$oauthVersion = "1.0";
$sigBase = "GET&" . rawurlencode($requestTokenUrl) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . $oauthTimestamp
. "&oauth_version=" . $oauthVersion);
Some of the above variables may be fairly obvious – $requestTokenUrl
was obtained from Twitter when you were granted consumer credentials, and $oauthTimestamp
is the current UNIX epoch time. The less obvious item is $nonce
, which is nothing more than a random string used only once (a difference nonce is used for each transaction). Typically an MD5-hashed random number works fine as a nonce. There is also $oauthSignatureMethod
which is always HMAC-SHA1 for Twitter, and the $oauthVersion
which is currently v1.0 for Twitter.
上面的一些变量可能是相当明显的-向您授予使用者凭据时,从Twitter获得了$requestTokenUrl
,而$oauthTimestamp
是当前的UNIX时期。 不太明显的项目是$nonce
,它只不过是只使用一次的随机字符串(每个事务使用差值随机数)。 通常,带有MD5哈希值的随机数可以作为随机数正常工作。 还有$oauthSignatureMethod
对于Twitter始终为HMAC-SHA1,而$oauthVersion
对于Twitter而言当前为v1.0。
Next, the string for the signature is constructed as $sigBase
. OAuth says that the signature base must be the HTTP method (GET
in this case) followed by an “&”, followed by the URL-encoded request URL ($requestTokenUrl
) followed by another “&”, and finally a URL-encoded and alphabetized list of parameter key/value pairs (the values of which must also be encoded) separated by “&”s. Note that when OAuth wants something URL-encoded, it means RFC-3986. PHP’s rawurlencode()
function works because it encodes spaces as “%20” instead of “+” as urlencode()
does.
接下来,用于签名的字符串构造为$sigBase
。 OAuth表示,签名库必须是HTTP方法(在这种情况下为GET
),后跟“&”,然后是URL编码的请求URL( $requestTokenUrl
),后跟另一个是“&”,最后是URL编码和按字母顺序排列的参数键/值对(也必须对其值进行编码)列表,以“&”分隔。 请注意,当OAuth需要某种经过URL编码的内容时,意味着RFC-3986 。 PHP的rawurlencode()
函数之所以起作用,是因为它将空格编码为“%20”,而不是像urlencode()
那样将“ +”编码为空格。
You also need a Signing Key. The key is always the Consumer Secret followed by an “&” and either 1) the OAuth Token Secret (which is part of the Token Credentials you don’t have yet), or 2) nothing. Then you can generate the final signature using PHP’s built-in hash_hmac()
function.
您还需要一个签名密钥。 密钥始终是“消费者密码”,后跟“&”,以及1)OAuth令牌密码(这是您尚未拥有的令牌凭证的一部分),或2)什么都没有。 然后,您可以使用PHP的内置hash_hmac()
函数生成最终签名。
<?php
$sigKey = $consumerSecret . "&";
$oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true));
You put all the pieces together to construct a URL to request the Request Credentials:
您将所有部分放在一起构造了一个URL,以请求请求凭证:
<?php
$requestUrl = $requestTokenUrl . "?"
. "oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . rawurlencode($oauthTimestamp)
. "&oauth_version=" . rawurlencode($oauthVersion)
. "&oauth_signature=" . rawurlencode($oauthSig);
$response = file_get_contents($requestUrl);
You’ll want a lot more error handling for anything beyond this simple demonstration, but for now I assume nothing will ever go wrong and you are able to receive the temporary Request Credentials in $response
.
除了这个简单的演示之外,您还需要更多的错误处理功能,但是现在,我认为不会出错,并且您可以通过$response
接收临时的请求凭证。
The response sent back from Twitter looks like this:
从Twitter发送回的响应如下所示:
oauth_token=mjeaYNdNYrvLBag6xJNWkxCbgL5DV6yPZl6j4palETU&oauth_token_secret=W45dnBz917gsdMqDu4bWNmShQq5A8pRwoLnJVm6kvzs&oauth_callback_confirmed=true
The oauth_token
and oauth_token_secret
values are extracted from the response and are used to construct the next link the user goes to for the second step in the authorization process. It’s a good idea to store the Request Credentials in the user’s session so they are available when the user returns from Twitter’s authorization page. The Authorization URL is provided on the Details page after registering your application with Twitter.
oauth_token
和oauth_token_secret
值是从响应中提取的,用于构造用户在授权过程的第二步中要使用的下一个链接。 将请求凭证存储在用户的会话中是一个好主意,以便当用户从Twitter的授权页面返回时可以使用它们。 向Twitter注册应用程序后,“详细信息”页面上会提供授权URL。
<?php
parse_str($response, $values);
$_SESSION["requestToken"] = $values["oauth_token"];
$_SESSION["requestTokenSecret"] = $values["oauth_token_secret"];
$redirectUrl = $authorizeUrl . "?oauth_token=" . $_SESSION["requestToken"];
header("Location: " . $redirectUrl);
Now that the application can send users to Twitter for authorization, it is a good time to add a Callback URL so Twitter can send them back to the application! The Callback URL is simply an address that Twitter will direct the user to after he has authorized your application to send tweets on his behalf, and is specified on the Detail page’s Settings tab.
现在,该应用程序可以将用户发送到Twitter进行授权,现在是添加回调URL的好时机,以便Twitter可以将他们发送回该应用程序! 回调URL只是Twitter在授权用户的应用程序代表其发送推文后将其定向到的地址,并在“详细信息”页面的“设置”选项卡上指定。
When Twitter redirects the user to the Callback URL, it appends two additional parameters: your oauth_token
from the initial request which can be used for verification, and oauth_verifier
which is used in obtaining the Authorization Credentials.
当Twitter将用户重定向到回调URL时,它会附加两个附加参数:来自初始请求的oauth_token
(可用于验证)和oauth_verifier
(用于获得授权凭证)。
Of the three sets of credentials needed to post tweets, you now have two – the Consumer Credentials and the Request Credentials. Next up: Access Credentials!
在发布推文所需的三组凭据中,您现在有两套-消费凭据和请求凭据。 下一步:访问凭据!
To obtain the Access Credentials you need the oauth_token
, oauth_token_secret
, and the newly obtained oauth_verifier
. This step requires another signed request, this time to the Access Token URL displayed on the Details page.
要获取访问凭据,您需要oauth_token
, oauth_token_secret
和新获得的oauth_verifier
。 此步骤需要另一个签名请求,这次是“详细信息”页面上显示的访问令牌URL。
<?php
$oauthVersion = "1.0";
$oauthSignatureMethod = "HMAC-SHA1";
$accessTokenUrl = "http://api.twitter.com/oauth/access_token";
$nonce = md5(mt_rand());
$oauthTimestamp = time();
$oauthVerifier = $_GET["oauth_verifier"];
The $accessTokenUrl
is the next endpoint obtained from the Details page. A new $oauthTimestamp
and $nonce
are generated, and $oauthVerifier
is sent back from the Twitter Authorization page. Not listed, but in the $_SESSION
array, are the request credentials from the previous step that are also required.
$accessTokenUrl
是从“详细信息”页面获得的下一个端点。 生成一个新的$oauthTimestamp
和$nonce
,并且从Twitter授权页面发送回$oauthVerifier
。 未列出,但在$_SESSION
数组中,还需要来自上一步的请求凭证。
This step of the authorization process requires another signed request. Once the signature is built, it is used with the request for Access Credentials.
授权过程的此步骤需要另一个已签名的请求。 构建签名后,它将与访问凭据请求一起使用。
<?php
$sigBase = "GET&" . rawurlencode($accessTokenUrl) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . rawurlencode($oauthTimestamp)
. "&oauth_token=" . rawurlencode($_SESSION["requestToken"])
. "&oauth_verifier=" . rawurlencode($oauthVerifier)
. "&oauth_version=" . rawurlencode($oauthVersion));
$sigKey = $consumerSecret . "&";
$oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true));
$requestUrl = $accessTokenUrl . "?"
. "oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . rawurlencode($oauthTimestamp)
. "&oauth_token=" . rawurlencode($_SESSION["requestToken"])
. "&oauth_verifier=" . rawurlencode($oauthVerifier)
. "&oauth_version=". rawurlencode($oauthVersion)
. "&oauth_signature=" . rawurlencode($oauthSig);
$response = file_get_contents($requestUrl);
This time $response
has the very useful screen_name
, user_id
and the much awaited Access Credentials!
这次$response
具有非常有用的screen_name
, user_id
和期待已久的访问凭据!
This concludes the authorization part of this article. So far you’ve learned how to create a new Twitter application and use the provided consumer credentials to step through the OAuth “dance” to obtain the access credentials. In the second and final part of this series I’ll discuss using the access credentials to post a tweet to the user’s Twitter stream.
到此结束本文的授权部分。 到目前为止,您已经了解了如何创建一个新的Twitter应用程序,以及如何使用提供的消费者凭据来逐步完成OAuth“舞蹈”以获取访问凭据。 在本系列的第二篇也是最后一部分中,我将讨论如何使用访问凭据将一条推文发布到用户的Twitter流中。
Image via Quin / Shutterstock
图片来自Quin / Shutterstock
oauth0 oauth2