-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Twitter OAuth using access_token #272
Comments
@maryokhin, there's any chance there's an |
@omab, I tried to pass it like this, but it gave me exactly the same error. Maybe I'm passing it wrong? twitter = {'oauth_token': oauth_token, 'oauth_token_secret': oauth_token_secret, 'oauth_verifier': oauth_verifier}
user = strategy.backend.do_auth(twitter) |
@maryokhin, right now it expects the |
@omab, I used the debugger and at line python-social-auth/social/backends/oauth.py Line 201 in bec5ff8
self.data.get('oauth_verifier') = None self.data = {'_content': '{ \r\n "backend": "twitter",\r\n "access_token": "2478001586-tbni3wKlT9***************8i2tdkiOW",\r\n "oauth_token_secret": "WgaYaEyHL*****************X6UpzAlTgITPa",\r\n "oauth_verifier": "Em5uMDvZU4G*****************NHDk6nCIYV0"\r\n}', '_content_type': 'application/json', 'csrfmiddlewaretoken': 'iOnr8epq2O*************VYBqZ'} Could it be that |
@maryokhin try defining this strategy in some place class DjangoRESTFrameworkStrategy(DjangoStrategy):
def request_data(self, merge=True):
if not self.request:
return {}
if merge:
data = self.request.REQUEST
elif self.request.method == 'POST':
data = self.request.POST
else:
data = self.request.GET
if data.get('_content'):
data = data.copy()
data.update(data.pop('_content'))
return data Then define this setting pointing to it: SOCIAL_AUTH_STRATEGY = 'path.to.your.strategy.DjangoRESTFrameworkStrategy' |
@omab, I implemented the strategy, but what is request.DATA = {'oauth_token_secret': 'WgaYaEyHL*****************X6UpzAlTgITPa', 'backend': 'twitter', 'oauth_verifier': 'Em5uMDvZU4G*****************NHDk6nCIYV0', 'access_token': '2478001586-tbni3wKlT9***************8i2tdkiOW'} On other hand I tried this, and got the same error as before. Was not able to use |
Even with the Looks like I need to review this process for OAuth1 backends. |
@omab, Yes, even with I used a custom strategy and return Data from some breakpoints: key = None secret = None oauth_verifier = Em5uMDvZU4G*****************NHDk6nCIYV0 token = {} token.get('oauth_token') = None token.get('oauth_token_secret') = None decoding = None If I modify this method: def oauth_auth(self, token=None, oauth_verifier=None,
signature_type=SIGNATURE_TYPE_AUTH_HEADER):
key, secret = self.get_key_and_secret()
oauth_verifier = oauth_verifier or self.data.get('oauth_verifier')
token_key = token.get('oauth_token') or self.data.get('access_token')
token_secret = token.get('oauth_token_secret') or self.data.get('oauth_token_secret')
# decoding='utf-8' produces errors with python-requests on Python3
# since the final URL will be of type bytes
decoding = None if six.PY3 else 'utf-8'
return OAuth1(key, secret,
resource_owner_key=token_key,
resource_owner_secret=token_secret,
callback_uri=self.redirect_uri,
verifier=oauth_verifier,
signature_type=signature_type,
decoding=decoding) Then the values of |
also have the same problem |
I am not sure if this is related, but I have also got a problem using the Twitter backend. I am trying to authenticate using
I set a breakpoint before the request was sent and manually added the query parameter and the missing header, and I got |
@maryokhin, @omritoptix, @Zoneur I've tried using AJAX to authenticate an user in the django example app (no Django REST Framework, but that shouldn't matter), and everything worked OK (I've tried Facebook, Google OAuth2 and Twitter), Twitter didn't needed the I've extended the example app with a simpler form to select a backend and input the |
@omab I wasn't able to get it to work with this code: class SocialAuthView(APIView):
serializer_class = SocialAuthSerializer
def post(self, request):
serializer = self.serializer_class(data=request.DATA, files=request.FILES)
if serializer.is_valid():
backend = serializer.data.get('backend')
access_token = serializer.data.get('access_token')
access_token_secret = serializer.data.get('access_token_secret')
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
strategy = load_strategy(request=request, backend=backend)
if isinstance(strategy.backend, BaseOAuth1):
token = {
'oauth_token': access_token,
'oauth_token_secret': access_token_secret
}
elif isinstance(strategy.backend, BaseOAuth2):
token = access_token
else:
raise Response(data="Wrong backend type", status=status.HTTP_400_BAD_REQUEST)
user = strategy.backend.do_auth(token)
login(request, user)
data = {'id': user.id, 'username': user.username}
return Response(data=data, status=status.HTTP_200_OK) Maybe @omritoptix or @Zoneur got it to work and can tell me what I'm doing wrong. P.S. |
@maryokhin, using |
@omab On OAuth 2 providers params
[('oauth_nonce', '9345058242317761441400449282'),
('oauth_timestamp', '1400449282'),
('oauth_version', '1.0'),
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_consumer_key', None),
('oauth_token', '2478001586-tbni3wKlT9***************8i2tdkiOW'),
('oauth_callback', 'http://127.0.0.1:8000/social-auth')] so during iteration it hits the |
Alright I got it to work. I have a function looking like this:
This works for Facebook, but failed for Twitter. I got it working by doing:
This seems weird because using the Twitter tool to generate cURL commands to authenticate, there is no need for the oauth_token_secret, but it fails if I do not include it. Also, is there a way to make this work without checking whether the backend is OAuth1 or OAuth2? I understand we are not in the regular PSA flow, but it would be nice not to check the base class of the backend. @maryokhin Your code looks rather similar to mine, try calling Thanks for your help @omab ! |
The |
@maryokhin I got it to work with both twitter and facebook by using @omab Example code.
and i use the following curl to invoke it (for example twitter):
I don't pass callback URL, and my callback url in the twitter settings in not related to my dev server. Hope it will help you in some way. |
@omritoptix, I don't know, even basically copying your code gives me the same error I had in the beginning. It's just driving me crazy. @strategy()
def social_auth(request, backend):
backend = request.strategy.backend
if isinstance(backend, BaseOAuth1):
token = {
'oauth_token': request.POST.get('access_token'),
'oauth_token_secret': request.POST.get('access_token_secret'),
}
elif isinstance(backend, BaseOAuth2):
token = request.POST.get('access_token')
else:
raise Response('Wrong backend type', status.HTTP_400_BAD_REQUEST)
user = request.strategy.backend.do_auth(token)
login(request, user)
data = {'username': user.username, 'api_key': user.api_key.key}
return Response(data=data, status=status.HTTP_200_OK) @omab, I guess just close the issue since I'm the only one experiencing difficulties. Thank you for all your input. |
@omab could it be by any chance something having to do with the setup I have or should I not even bother checking that? I communicated with @Zoneur and using the exact same code that works for him doesn't work for me. It would be valuable, if @omritoptix could share his environment. I use Django==1.7b4
django-braces==1.4.0
django-cors-headers==0.12
django-grappelli==2.5.3
djangorestframework==2.3.13
oauthlib==0.6.1
psycopg2==2.5.3
python-social-auth==0.1.24
python3-openid==3.0.4
requests==2.3.0
requests-oauthlib==0.3.1
shortuuid==0.4.2
six==1.6.1 |
@maryokhin, are you settings defined properly? |
@omab, I get a 401 now, but that means it works! Thank you very much, I did not include the keys on the API side, because it worked without them on OAuth2, but I guess OAuth1 requires it, I didn't know about this requirement. Thank you and I now feel stupid about my mistake. P.S. I think Django REST Framework should be included to the list of frameworks, I can contribute a simple example app in ~ week's time. |
@maryokhin, not sure what you meant with About Django REST Frameworks support as a built-in app, that would be great to have. |
@omab, I meant that for Google/Facebook I didn't define any keys/secrets in the settings and it worked. |
Cool, I'm gonna close this issue since it's finally solved, thanks! |
Using SOCIAL_AUTH_TWITTER_KEY and SOCIAL_AUTH_TWITTER_SECRET as configuration parameters, as proposed, solved this for me. Here is the pull request for the documentation update: |
I am using Django REST Framework + Python-Social-Auth. I already got Facebook and Google OAuth2 working, but am having a problem using the same code to connect Twitter. I am having the same error as #107, but solution does not work because all work is done on the client and I have to work with keys in the request:
I also tried to do something like this:
But no matter what I tried, I always got the same stacktrace
Any help would be appreciated, thank you.
The text was updated successfully, but these errors were encountered: