1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
================
Using the Client
================
**Are you using requests?**
If you then you should take a look at `requests-oauthlib`_ which has several
examples of how to use OAuth1 with requests.
.. _`requests-oauthlib`: https://github.com/requests/requests-oauthlib
**Signing a request with an HMAC-SHA1 signature (most common)**
See `requests-oauthlib`_ for more detailed examples of going through the
OAuth workflow. In a nutshell you will be doing three types of requests, to
obtain a request token, to obtain an access token and to access a protected
resource.
Obtaining a request token will require client key and secret which are
provided to you when registering a client with the OAuth provider::
client = oauthlib.oauth1.Client('client_key', client_secret='your_secret')
uri, headers, body = client.sign('http://example.com/request_token')
You will then need to redirect to the authorization page of the OAuth
provider, which will later redirect back with a verifier and a token secret
parameter appended to your callback url. These will be used in addition to
the credentials from before when obtaining an access token::
client = oauthlib.oauth1.Client('client_key', client_secret='your_secret',
resource_owner_secret='the_new_secret', verifier='the_verifier')
uri, headers, body = client.sign('http://example.com/access_token')
The provider will now give you an access token and a new token secret which
you will use to access protected resources::
client = oauthlib.oauth1.Client('client_key', client_secret='your_secret',
resource_owner_key='the_access_token', resource_owner_secret='the_token_secret')
uri, headers, body = client.sign('http://example.com/access_token')
.. _`requests-oauthlib`: https://github.com/requests/requests-oauthlib
**Unicode Everywhere**
Starting with 0.3.5 OAuthLib supports automatic conversion to unicode if you
supply input in utf-8 encoding. If you are using another encoding you will
have to make sure to convert all input to unicode before passing it to
OAuthLib. Note that the automatic conversion is limited to the use of
oauthlib.oauth1.Client.
**Request body**
The OAuth 1 spec only covers signing of x-www-url-formencoded information.
If you are sending some other kind of data in the body (say, multipart file
uploads), these don't count as a body for the purposes of signing. Don't
provide the body to Client.sign() if it isn't x-www-url-formencoded data.
For convenience, you can pass body data in one of three ways:
* a dictionary
* an iterable of 2-tuples
* a properly-formated x-www-url-formencoded string
**RSA Signatures**
OAuthLib supports the 'RSA-SHA1' signature but does not install the PyCrypto
dependency by default. This is not done because PyCrypto is fairly
cumbersome to install, especially on Windows. Linux and Mac OS X (?) users
can install PyCrypto using pip::
pip install pycrypto
Windows users will have to jump through a few hoops. The following links may be helpful:
* `Voidspace Python prebuilt binaries for PyCrypto <http://www.voidspace.org.uk/python/modules.shtml#pycrypto>`_
* `Can I install Python Windows packages into virtualenvs <http://stackoverflow.com/questions/3271590/can-i-install-python-windows-packages-into-virtualenvs>`_
* `Compiling pycrypto on Windows 7 (64bit) <http://yorickdowne.wordpress.com/2010/12/22/compiling-pycrypto-on-win7-64/>`_
When you have pycrypto installed using RSA signatures is similar to HMAC but
differ in a few aspects. RSA signatures does not make use of client secrets
nor resource owner secrets (token secrets) and requires you to specify the
signature type when constructing a client::
client = oauthlib.oauth1.Client('your client key',
signature_method=oauthlib.oauth1.SIGNATURE_RSA,
resource_owner_key='a token you have obtained',
rsa_key=open('your_private_key.pem').read())
**Plaintext signatures**
OAuthLib supports plaintext signatures and they are identical in use to
HMAC-SHA1 signatures except that you will need to set the signature_method
when constructing Clients::
client = oauthlib.oauth1.Client('your client key',
client_secret='your secret',
resource_owner_key='a token you have obtained',
resource_owner_secret='a token secret',
signature_method=oauthlib.oauth1.SIGNATURE_PLAINTEXT)
**Where to put the signature? Signature types**
OAuth 1 commonly use the Authorization header to pass the OAuth signature
and other OAuth parameters. This is the default setting in Client and need
not be specified. However you may also use the request url query or the
request body to pass the parameters. You can specify this location using the
signature_type constructor parameter, as shown below::
>>> # Embed in Authorization header (recommended)
>>> client = oauthlib.oauth1.Client('client_key',
signature_type=SIGNATURE_TYPE_AUTH_HEADER,
)
>>> uri, headers, body = client.sign('http://example.com/path?query=hello')
>>> headers
{u'Authorization': u'OAuth oauth_nonce="107143098223781054691360095427", oauth_timestamp="1360095427", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="client_key", oauth_signature="86gpxY1DUXSBRRyWnRNJekeWEzw%3D"'}
>>> # Embed in url query
>>> client = oauthlib.oauth1.Client('client_key',
signature_type=SIGNATURE_TYPE_QUERY,
)
>>> uri, headers, body = client.sign('http://example.com/path?query=hello')
>>> uri
http://example.com/path?query=hello&oauth_nonce=97599600646423262881360095509&oauth_timestamp=1360095509&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&oauth_consumer_key=client_key&oauth_signature=VQAib%2F4uRPwfVmCZkgSE3q2p7zU%3D
>>> # Embed in body
>>> client = oauthlib.oauth1.Client('client_key',
signature_type=SIGNATURE_TYPE_BODY,
)
>>> # Please set content-type to application/x-www-form-urlencoded
>>> headers = {'Authorization':oauthlib.oauth1.CONTENT_TYPE_FORM_URLENCODED}
>>> uri, headers, body = client.sign('http://example.com/path?query=hello',
headers=headers)
>>> body
u'oauth_nonce=148092408248153282511360095722&oauth_timestamp=1360095722&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&oauth_consumer_key=client_key&oauth_signature=5IKjrRKU3%2FIduI9UumVI%2FbQ0Hv0%3D'
|