loading...
Cover image for Simplifying "Login With Twitter" using Python and Flask.

Simplifying "Login With Twitter" using Python and Flask.

m4cs profile image Max Bridgland ・5 min read

Recently while working on a project I came across an issue with trying to implement Twitter Integrations into my Flask app. All of the guides on Google were breaking or just didn’t fit in with my application. I wanted a simple way to interface with Twitter’s OAuth1 API but everything was giving me errors.

NOTE: This guide assumes you have setup a Twitter Application and have your consumer keys and callback URLs set. If you do not know how to do this please refer to this guide.

Finally, I decided to try something myself, I looked into requests_oauthlib and realized it would be much easier to just use their Client class to generate signatures and implement with my Flask app. I couldn’t find any examples that were easy to understand or read as far as the code went so I wanted to share how I ended up implementing this into my application.

First the libraries I used in my implementation. flask is the library I’m using in order to create my main webserver and viewable routes. We don’t use much apart from the redirect function from it in this. flask_restful is the REST library I’m using in order to easily create a JSON based API. The endpoints we create in this are RESTful API Endpoints that inherit the Resource class from flask_restful. requests_oauthlib is the OAuth library I use in order to generate the OAuth headers to authenticate with Twitter’s API. We will also be using the requests library in order to make requests server side to Twitter.

First you need to setup a flask app. Lets make a folder called app first:

mkdir ./app
cd ./app
Enter fullscreen mode Exit fullscreen mode

Now from within the app/ directory we will create a file called init.py :

# Let's import the Flask class from the flask library
from flask import Flask

# Let's import the Api class from the flask_restful library
from flask_restful import Api

# Let's import our OAuth library to setup
from requests_oauthlib.oauth1_auth import Client

# Create A Config To Store Values
config = {
    'twitter_consumer_key': 'ENTER TWITTER CONSUMER KEY',
    'twitter_consumer_secret': 'ENTER TWITTER CONSUMER SECRET'
}

# Initialize Our Flask App
app = Flask(__name__)

# Initialize Our RESTful API
api = Api(app)

# Initialize Our OAuth Client
oauth = Client(config['twitter_consumer_key'], client_secret=config['twitter_consumer_secret'])
Enter fullscreen mode Exit fullscreen mode

This is all we need to do for now in the init.py file. Next we will start to create our endpoints for Twitter. This assumes you have setup a Twitter Application and you have your consumer keys.

Next we create our endpoint. For this we can just create a file called twitter.py or really whatever you’d like. Next we add:

# Import our functions and Resource class from flask_restful
from flask_restful import Resource, reqparse

# Import our functions from Flask
from flask import redirect

# Import our oauth object from our app
from app import oauth

# Import requests in order to make server sided requests
import requests

# We have to create our initial endpoint to login with twitter
class TwitterAuthenticate(Resource):
    # Here we are making it so this endpoint accepts GET requests
    def get(self):
        # We must generate our signed OAuth Headers
        uri, headers, body = oauth.sign('https://twitter.com/oauth/request_token')
        # We need to make a request to twitter with the OAuth parameters we just created
        res = requests.get(uri, headers=headers, data=body)
        # This returns a string with OAuth variables we need to parse
        res_split = res.text.split('&') # Splitting between the two params sent back
        oauth_token = res_split[0].split('=')[1] # Pulling our APPS OAuth token from the response.
        # Now we have to redirect to the login URL using our OAuth Token
        return redirect('https://api.twitter.com/oauth/authenticate?oauth_token=' + oauth_token, 302)
Enter fullscreen mode Exit fullscreen mode

This is our authentication endpoint, when somebody attempts to hit this it will redirect them to the Twitter login page which will then send them to our Callback URL which you should have setup in your Twitter App’s dashboard.

Next we need to add the logic for handling our callback URL. We can add this to the same file as the TwitterAuthenticate class.

# We need to create a parser for that callback URL
def callback_parser():
    parser = reqparse.RequestParser()
    parser.add_argument('oauth_token')
    parser.add_argument('oauth_verifier')
    return parser

# Now we setup the Resource for the callback
class TwitterCallback(Resource):
    def get(self):
        parser = callback_parser()
        args = parser.parse_args() # Parse our args into a dict
        # We need to make a request to twitter with this callback OAuth token
        res = requests.post('https://api.twitter.com/oauth/access_token?oauth_token=' + args['oauth_token'] + '&oauth_verifier=' + args['oauth_verfier']])
        res_split = res.text.split('&')
        # Now we need to parse our oauth token and secret from the response
        oauth_token = res_split[0].split('=')[1]
        oauth_secret = res_split[1].split('=')[1]
        userid = res_split[2].split('=')[1]
        username = res_split[3].split('=')[1]
        # We now have access to the oauth token, oauth secret, userID, and username of the person who logged in. 
        # .... Do more code here
        # ....
        return redirect('http://somwhere.com", 302)
Enter fullscreen mode Exit fullscreen mode

This TwitterCallback class will parse and handle the OAuth tokens in order to access the user’s account info. You can do whatever you want with this info whether that be storing it into a DB User Model or making requests with Tweepy!

The last step is adding these endpoints to your init.py file we created at the beginning! At the bottom of the file add this:

from app.twitter import TwitterAuthenticate, TwitterCallback

api.add_resource(TwitterAuthenticate, '/authenticate/twitter')
api.add_resource(TwitterCallback, '/callback/twitter') # This MUST match your Callback URL you set in the Twitter App Dashboard!!!
Enter fullscreen mode Exit fullscreen mode

Our final twitter.py should look like this:

from flask_restful import Resource, reqparse
from flask import redirect
from app import oauth
import requests
class TwitterAuthenticate(Resource):
    def get(self):
        uri, headers, body = oauth.sign('[https://twitter.com/oauth/request_token'](https://twitter.com/oauth/request_token'))
        res = requests.get(uri, headers=headers, data=body)
        res_split = res.text.split('&') # Splitting between the two params sent back
        oauth_token = res_split[0].split('=')[1] # Pulling our APPS OAuth token from the response.
        return redirect('[https://api.twitter.com/oauth/authenticate?oauth_token='](https://api.twitter.com/oauth/authenticate?oauth_token=') + oauth_token, 302)

def callback_parser():
    parser = reqparse.RequestParser()
    parser.add_argument('oauth_token')
    parser.add_argument('oauth_verifier')
    return parser

class TwitterCallback(Resource):
    def get(self):
        parser = callback_parser()
        args = parser.parse_args() # Parse our args into a dict
        res = requests.post('[https://api.twitter.com/oauth/access_token?oauth_token='](https://api.twitter.com/oauth/access_token?oauth_token=') + args['oauth_token'] + '&oauth_verifier=' + args['oauth_verfier']])
        res_split = res.text.split('&')
        oauth_token = res_split[0].split('=')[1]
        oauth_secret = res_split[1].split('=')[1]
        userid = res_split[2].split('=')[1]
        username = res_split[3].split('=')[1]
        # ... Do Code Here
        return redirect('[http://somwhere.com](http://somwhere.com)", 302)
Enter fullscreen mode Exit fullscreen mode

Our final init.py should look something like:

from flask import Flask
from flask_restful import Api
from requests_oauthlib.oauth1_auth import Client

config = {
    'twitter_consumer_key': 'ENTER TWITTER CONSUMER KEY',
    'twitter_consumer_secret': 'ENTER TWITTER CONSUMER SECRET'
}

app = Flask(__name__)
api = Api(app)
oauth = Client(config['twitter_consumer_key'], client_secret=config['twitter_consumer_secret'])

from app.twitter import TwitterAuthenticate, TwitterCallback

api.add_resource(TwitterAuthenticate, '/authenticate/twitter')
api.add_resource(TwitterCallback, '/callback/twitter')
Enter fullscreen mode Exit fullscreen mode

I hope you find this guide helpful and have a fun time integrating with Twitter’s User API!

You can find a GitHub Gist here with the files shown above.

Follow me on Twitter and GitHub for more interesting programming stuff!

Discussion

pic
Editor guide