在Django中对URL字符串执行POST

时间:2013-08-16 18:26:30

标签: python django post linkedin

我正在使用LinkedIn身份验证:http://developer.linkedin.com/documents/authentication,我需要发帖。我熟悉GET请求,例如:

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

使用了Oauth身份验证。但是对于身份验证的Post部分,我必须POST一个示例字符串,例如:

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

我的简单问题涉及理解最好的方法是什么 - 不使用Oauth(假设这是正确的方法),因为我已经返回了AUTHORIZATION_CODE。如果这是一个简单的问题,请道歉。

换句话说,我有一个上述形式的字符串,现在,如何执行帖子?

我尝试过使用cURL。但是我发现代码在发布行时失败了:c.perform()。这是我正在使用的代码:

   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()

我收到以下错误:

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

以下是我如何获得身份验证的第一阶段的代码(正如LI文档所建议的那样):

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)

以下是使用下面建议的代码发布数据后我得到的最新回溯。在跟踪之后,我将提出一些问题。

错误:

HTTPConnectionPool(host ='127.0.0.1',port = 8888):使用url:https://api.linkedin.com/uas/oauth/accessToken超出了最大重试次数(由此引起:[Errno 111]拒绝连接)

环境:

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)

加上请求信息,它看起来仍然没有POST数据:

请求信息

GET 变量值 状态
u'XX” 代码
u'XX” POST 无更新数据 FILES 没有文件数据

以下是更多细节。

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

1 个答案:

答案 0 :(得分:15)

看看requests(使用pip install requests安装),只需几行代码即可轻松发出POST请求:

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)

你可以在Python shell中试试这个,因为我觉得它很简单。