Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing POST on a URL string in Django

I'm using the LinkedIn Authentication at: http://developer.linkedin.com/documents/authentication and I need to make a post. I'm familiar with making a GET request for example as:

client = oauth.Client(consumer, access_token)
resp,content = client.request("http://api.linkedin.com/v1/people/~?format=json", "GET", "")

Which used Oauth authentication. However for the Post part of the authentication, I have to POST an example string such as:

https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code
                                           &code=AUTHORIZATION_CODE
                                           &redirect_uri=YOUR_REDIRECT_URI
                                           &client_id=YOUR_API_KEY
                                           &client_secret=YOUR_SECRET_KEY

and my simple question relates to understanding what the best way to do this is - without using the Oauth (assuming that is the correct approach), since I have returned the AUTHORIZATION_CODE. Apologies if this is a simple question.

So in other words, I have a string of the above form, now, How do I perform a post?

I've tried using cURL. But I find the code fails at the post line: c.perform(). Here is the code I am using:

   accesscode = request.GET.get('code')
    redirect_uri = 'http://www.example.com'
    url_post = 'https://www.linkedin.com/uas/oauth2/accessToken'
    postdata = urllib2.quote('grant_type=authorization_code&code='+accesscode+'&redirect_uri='+redirect_uri+'&client_id='+consumer_key+'&client_secret='+consumer_secret)
    #return HttpResponse(postdata)

    c = pycurl.Curl()
    c.setopt(c.URL, url_post)
    c.setopt(c.POSTFIELDS, postdata)
    c.setopt(c.VERBOSE, True)
    c.setopt(c.FAILONERROR, True)
    c.perform()

I'm getting the following error:

error at /loginsuccess/
(22, 'The requested URL returned error: 400 Bad Request')

Here is the code for how I am obtaining the first stage of the Authentication (as is suggested by the LI documentation):

def login(request):
    redirect_uri       =   urllib2.quote('http://127.0.0.1:8080/loginsuccess')
    codeURL = "https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=c3skrqz5wqmm&scope=r_fullprofile&state=DCEEFWF45453sdffef425&redirect_uri=" + redirect_uri
    return HttpResponseRedirect(codeURL)

Here is the latest traceback that I am getting after using the code suggested below to post the data. I have a number of questions that I will outline after the trace.

Error:

HTTPConnectionPool(host='127.0.0.1', port=8888): Max retries exceeded with url: https://api.linkedin.com/uas/oauth/accessToken (Caused by : [Errno 111] Connection refused)

Environment:

Request Method: GET
Request URL: http://127.0.0.1:9000/loginsuccess/?code=AQQKMnhjMNKFEu08DkftejkNLQgSz-mIsMZtE36rGxrLfycx331iLXeC3LdAq63OTQeATAEXrA7FxgHSJWVHyh_iWyIEzVR6jp4zJsz41tpRipS14RE&state=DCEEFWF45453sdffef425

Django Version: 1.4.5
Python Version: 2.7.4
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/brett/LinkedIn/brett/brett/views.py" in loginsuccess
  68.   r = requests.post(access_token_url, data=postdata)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py" in post
  88.     return request('post', url, data=data, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py" in request
  44.     return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py" in request
  335.         resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py" in send
  438.         r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py" in send
  327.             raise ConnectionError(e)

Exception Type: ConnectionError at /loginsuccess/
Exception Value: HTTPConnectionPool(host='127.0.0.1', port=8888): Max retries exceeded with url: https://api.linkedin.com/uas/oauth/accessToken (Caused by <class 'socket.error'>: [Errno 111] Connection refused)

Plus with the request information there is still no POST data it would seem:

Request information

GET Variable Value state
u'XX' code
u'XX' POST No POST data FILES No FILES data

Here is more details.

Request Method: GET
Request URL:    http://127.0.0.1:9000/loginsuccess/?code=XXX&state=XXX
Django Version: 1.4.5
Exception Type: ConnectionError
Exception Value:    
HTTPConnectionPool(host='127.0.0.1', port=8888): Max retries exceeded with url: https://api.linkedin.com/uas/oauth/accessToken (Caused by <class 'socket.error'>: [Errno 111] Connection refused)
Exception Location: /usr/local/lib/python2.7/dist-packages/requests/adapters.py in send, line 327
Python Executable:  /usr/bin/python

Fiddler results:

HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
P3P: CP="CAO DSP COR CUR ADMi DEVi TAIi PSAi PSDi IVAi IVDi CONi OUR DELi SAMi UNRi PUBi OTRi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT POL PRE"
X-LI-UUID: dI14TYAfd/RHJ8mVmAN8Gg==
Location: http://127.0.0.1:9000/loginsuccess?code=XX=XX
Content-Language: en-US
Content-Encoding: gzip
Vary: Accept-Encoding
Date: Thu, 05 Sep 2013 19:26:48 GMT
X-Li-Fabric: PROD-ELA4
Set-Cookie: _lipt=deleteMe; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Set-Cookie: leo_auth_token="XX"; Version=1; Max-Age=1799; Expires=Thu, 05-Sep-2013 19:56:47 GMT; Path=/
Set-Cookie: sl="delete me"; Version=1; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Set-Cookie: sl="delete me"; Version=1; Domain=.www.linkedin.com; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Set-Cookie: lang="v=2&lang=en-us"; Version=1; Domain=linkedin.com; Path=/
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store
Age: 1
Transfer-Encoding: chunked
Connection: keep-alive
X-Li-Pop: PROD-IDB2

14
�����������������
0
like image 655
disruptive Avatar asked Aug 16 '13 18:08

disruptive


1 Answers

Take a look at requests (install with pip install requests), you can make the POST request easily with just some lines of code:

import requests

accesscode = request.GET.get('code')
redirect_uri = 'http://www.example.com'
url = 'https://www.linkedin.com/uas/oauth2/accessToken'
# ... your code ...

postdata = {
    'grant_type': 'authorization_code',
    'code': accesscode,
    'redirect_uri': redirect_uri,
    'client_id': consumer_key,
    'client_secret': consumer_secret,
}

r = requests.post(url, data=postdata)
print(r.status_code)
print(r.text)

You can try this in Python shell since I think it's simple enough to do so.

like image 64
Hieu Nguyen Avatar answered Sep 21 '22 13:09

Hieu Nguyen