Twitter OAuth Authentication with Elixir and Phoenix

There are a few good examples showing how to use OAuth authentication in Phoenix and Elixir, but I wanted a solution which used a small amount of dependencies, and had the ability to make authenticated requests on behalf of a user.

parroty/extwitter provides the functionality to authenticate as a user, as well as to make requests on behalf of that user. I wanted to just use this library, and avoid adding the additional dependencies of ueberauth and guardian.

Full code is available at: https://github.com/steveklebanoff/twitter_oauth_example

Here’s a breakdown of some of the interesting parts:

AuthController

We start off authenticating via twitter in the request function. This generates and redirects the user to a URL which will prompt them to authorize our application via twitter.

If the user authorizes, they will be redirected to our callback function with oauth information in the request parameters. We use ExTwitter to generate an access token based on oauth_verifier and oauth_token which was provided by twitter as URL parameters. We then configure ExTwitter to use the access_token and access_token_secret we received. This allows us to make verified requests on behalf of this twitter user.

Now that we can make verified requests, we call verify_credentials to ensure everything is kosher, and also to receive information about the user’s twitter account. We take a subset of that information (name and screen_name) and set it on the session as current_user.

We also store the access_token and access_token_secret on the session, so we can make further authenticated requests later. At the time of writing, twitter does not expire these tokens. Because Phoenix uses Plug.Session.COOKIE, which is “based on Plug.Crypto.MessageVerifier and Plug.Crypto.Message.Encryptor which encrypts and signs each cookie to ensure they can’t be read nor tampered with”, we can feel confident that this information will be safe.

Plugs

We define three plugs which help our controllers work. These plugs are similar to rails controller before_filter in that they are executed before controller code.

The first, AssignCurrentUser, just allows us to access current_user through conn.assigns.current_user instead of having to do get_session(conn, :current_user) every time.

The second, RequireUser allows us to limit certain controller actions to only be available to signed in users.

The third, ConfigureTwitterClient sets up our ExTwitter client to have the user’s access_token and access_secret configured for any twitter API call made by a signed-in user.

TweetController

With authentication already handled, and ConfigureTwitterClient already setting up ExTwitter for authenticated users, the TweetController is very small and simple. It uses ExTwitter to grab a user’s timeline, and to post a new tweet.

Putting It All Together

You can run the app see how the whole thing comes together in the code published at steveklebanoff/twitter_oauth_example.

If you see anywhere in which the code could be improved, please holler at me in the comments here, or in a Github issue or PR.

Other Resources and Acknowledgements

ueberauth/ueberauth_twitter is an awesome example of how to do authentication via Twitter using ueberauth. That being said, it doesn’t provide functionality to make authenticated requests on behalf of a user, and if you use parroty/extwitter you don’t necessarily need the ueberauth dependency.

scrogson/oauth2_example has great examples on how to do OAuth 2 Authentication via a variety of providers, but it does not support Twitter which uses OAuth 1.

Thanks to cjlarose for taking some time to discuss the security aspects of storing OAuth tokens in cookies.

Leave a Reply

Your email address will not be published. Required fields are marked *