Neara
Neara

Reputation: 3781

Twython - How to associate multiple twitter accounts with one user

I want to allow registered users to add multiple twitter accounts. I followed twython-django example, and got a working version of one user - one twitter account. If the user tries to use twitter login again, follows same view again, I get this error: Invalid / expired Token.

I tried adding force_login=true to oauth/authorize and oauth/authenticate, removing 'request_token' from request.session dict, but i still get Invalid Token error during get_authentication_tokens().

How to properly associate multiple twitter accounts with the same user, using twython? What am I missing here?

Here is an a twython-django example: https://github.com/ryanmcgrath/twython-django/blob/master/twython_django_oauth/views.py

My view:

def twitter_login(request):
    redirect_back_to_url = request.build_absolute_uri()

    if 'request_token' not in request.session:
        # request authorization tokens
        t = Twython(twitter_token=settings.TWITTER_CONSUMER_KEY,
                    twitter_secret=settings.TWITTER_CONSUMER_SECRET,
                    callback_url=redirect_back_to_url)

        # Request an authorization url to send the user to...
        request_oauth_key = t.get_authentication_tokens()

        # signing current session as one with twitter authentication
        request.session['request_token'] = request_oauth_key

        # redirecting the user to twitter authorization url for authentication
        return HttpResponseRedirect(request_oauth_key['auth_url'])
    else:
        # user authenticated, receiving auth token
        t2 = Twython(twitter_token=settings.TWITTER_CONSUMER_KEY,
                     twitter_secret=settings.TWITTER_CONSUMER_SECRET,
                     oauth_token=request.session['request_token'][
                         'oauth_token'],
                     oauth_token_secret=request.session['request_token'][
                         'oauth_token_secret'])

        oauth_key = t2.get_authorized_tokens()

        # save authorized tokens
        # twitter oauth tokens dont expire
        token = Token.objects.get_or_create(account_name=oauth_key['screen_name'],
                                            token=oauth_key['oauth_token'],
                                            secret=oauth_key['oauth_token_secret'])
        user = request.user.get_profile()
        user.twitter.add(token[0].id)
        user.save()

        logger.info('Successfully acquired twitter oauth token.')

        return HttpResponseRedirect(reverse('profile'))

Update: possible solution

I changed my view to this:

def twitter_login(request):
    redirect_back_to_url = request.build_absolute_uri()

    if 'request_token' not in request.session:
        # request authorization tokens
        t = Twython(twitter_token=settings.TWITTER_CONSUMER_KEY,
                    twitter_secret=settings.TWITTER_CONSUMER_SECRET,
                    callback_url=redirect_back_to_url)

        # Request an authorization url to send the user to...
        request_oauth_key = t.get_authentication_tokens()

        # signing current session as one with twitter authentication
        request.session['request_token'] = request_oauth_key

        # redirecting the user to twitter authorization url for authentication
        return HttpResponseRedirect(request_oauth_key['auth_url'])
    else:
        # user authenticated, receiving auth token
        t2 = Twython(twitter_token=settings.TWITTER_CONSUMER_KEY,
                     twitter_secret=settings.TWITTER_CONSUMER_SECRET,
                     oauth_token=request.session['request_token'][
                         'oauth_token'],
                     oauth_token_secret=request.session['request_token'][
                         'oauth_token_secret'])

        oauth_key = t2.get_authorized_tokens()
        if 'screen_name' not in oauth_key:
            del request.session['request_token']
            request.session.modified = True
            return HttpResponseRedirect(reverse('twitter_login'))

        # save authorized tokens
        # twitter oauth tokens dont expire
        token = Token.objects.get_or_create(account_name=oauth_key['screen_name'],
                                            token=oauth_key['oauth_token'],
                                            secret=oauth_key['oauth_token_secret'])
        user = request.user.get_profile()
        user.twitter.add(token[0].id)
        user.save()

        logger.info('Successfully acquired twitter oauth token.')

        return HttpResponseRedirect(reverse('profile'))

And not sure yet if this had anything to do with it. I added after line 272 in twython.py request_args['force_login'] = True. But, as i said, i'm not sure if that had any impact, cos according to https://dev.twitter.com/docs/api/1/post/oauth/request_token force login is not one of the optional args.

Some voodoo this was. lol. Tell me if its a total rubbish.

Upvotes: 1

Views: 965

Answers (1)

Ryan McGrath
Ryan McGrath

Reputation: 2042

Mmm, I believe OP got it working/right, but just as a quick breakdown, twython-django isn't built to support multiple account associations (it's also not on Django 1.5, so be careful with that until it's updated~).

You'd need to do what OP did and set up a separate table for Tokens that match over to a User, and then handle which account they're currently using by pulling the appropriate tokens. OPs use of force_login also seems to have worked because, while it's not necessarily documented, I believe it still works (according to this thread, unless I'm misreading it - if I am, I would love to be corrected).

I don't expect this answer to be accepted as I'm not really solving anything, but if anyone else encounters this I'm hoping to leave something more clear-cut than the above notes. Hope that's alright!

Upvotes: 1

Related Questions