Twitter Authentication in Sinatra

Share this article

sinatra_twitter
At the recent Summit Awesome Hackathon in Manchester, my team were working on a web app that updated a user’s bio on various social networks in one place. This meant getting down and dirty with various social network APIs (not a pretty thing I can tell you). I thought I’d do a quick write up on how you can authenticate users in a Sinatra app by allowing them to sign in with Twitter.

Set Up The Site

To demonstrate this working, first of all, let’s set up a simple app that has two urls – public and private. Save the following code in a file called ‘main.rb’:
require 'sinatra'

helpers do
  def admin?
    true
  end
end

get '/public' do
  "This is the public page - everybody is welcome!"
end

get '/private' do
  halt(401,'Not Authorized') unless admin?
  "This is the private page - members only"
end
This sets up a helper method called admin? that we can use to check if a user is logged in. It’s set to true by default to enable us to check that things work. We’ve also set up two route handlers. The first is for the route ‘/public’, which shows a message to everybody who visits. The second route is a private page that will only show the message if the admin? helper returns true. If not, then we use Sinatra’s halt method to stop the app in it’s tracks and show a ‘Not Authorized’ message. To check that this happens, change the admin? helper method to false, restart the server (ruby main.rb) and go to ‘http://localhost:4567/private’.

Using Sessions to Log in and Out

We can add some route handlers to allow the user to log in and out and use sessions to keep track of whether a user is logged in or not. Change the code in main.rb to the following:
require 'sinatra'

configure do
  enable :sessions
end

helpers do
  def admin?
    session[:admin]
  end
end

get '/public' do
  "This is the public page - everybody is welcome!"
end

get '/private' do
  halt(401,'Not Authorized') unless admin?
  "This is the private page - members only"
end

get '/login' do
  session[:admin] = true
  "You are now logged in"
end

get '/logout' do
  session[:admin] = nil
  "You are now logged out"
end
Now restart the server and try going to ‘http://localhost:4567/login’, then go to ‘http://localhost:4567/private’, and you should be able to see the page. Go to ‘http://localhost:4567/logout’, then try ‘http://localhost:4567/private’ again, and you should get the ‘unauthorized’ message. Great – we have a working log in and log out system. The next step is to use Twitter to authenticate the user instead of just allowing anybody to log in using the login url.

Register Your App with Twitter

Before you can start using Twitter to sign in, you need to register your app with Twitter. This is easily done – just head over to https://dev.twitter.com/apps and log in using your Twitter credentials. Then click on the ‘create a new application’ button and fill in the form. You can pick any name for your application (as long as it doesn’t contain the word ‘Twitter’) and can use any website as a placeholder until you get an actual domain name for your application. For example, I used http://www.sitepoint.com. In the callback URL field, you need to add /auth/twitter/callback to whichever URL you used in the website field. For example, I used https://www.sitepoint.com/auth/twitter/callback. You will then be taken to a page that contains the OAuth settings for your application. Make a note of the ‘consumer key’ and ‘consumer secret’ as we will be using them in our app.

Ominauth

The library we are going to use to authenticate with is called ‘omniauth’. As the name suggests, it can actually be used to authenticate with a variety of services such as GitHub and Facebook, amongst others. It is split into different modules based on the service being used, so in this case we need to install the omniauth-twitter gem:
$ gem install omniauth-twitter
Next, you need to set up ominauth which can be done at the top of main.rb:
require 'sinatra'
require 'omniauth-twitter'

use OmniAuth::Builder do
  provider :twitter, 'put your consumer key here', 'put your consumer secret here'
end

Sign in with Twitter

We need to create the sign in with Twitter functionality. First of all, we’ll edit our ‘/login’ route handler so that it redirects to the URL that has automatically been set up by Omniauth:
get '/login' do
  redirect to("/auth/twitter")
end
Note that if you were using GitHub, the URL would be “/auth/github”. This will take the user into Twitter and ask them if it’s okay to allow your app to access Twitter. If sign in is successful, it triggers a callback to ‘/auth/twitter/callback’. All we need to do now is create a route handler to deal with what we want to happen when log in is successful. This is just the same code that we used earlier in the login route handler:
get '/auth/twitter/callback' do
  env['omniauth.auth'] ? session[:admin] = true : halt(401,'Not Authorized')
  "You are now logged in"
end
There is also a route for handling an unsuccessful login, which we need to create a handler for:
get '/auth/failure' do
  params[:message]
end
This displays the message that is sent back from Twitter as to why the authentication failed. Now we have a fully functional login system that uses Twitter for authentication. This is one of the things I love about Sinatra – we’ve whipped up a fully functional login system that uses Twitter for authentication in around 40 lines of code!

Using the Twitter Credentials

Now that we have somebody logged in with Twitter, what can we do? When a user logs in with Twitter, you actually gain access to a lot of information about them. This is stored in a hash called env['omniauth.auth']
. To see what this looks like, change the callback route handler to the following:
get '/auth/twitter/callback' do
  session[:admin] = true
  env['omniauth.auth']
end
Now try loggin in using Twitter and you will see all the information from your Twitter account that is held in the hash. For example, you could welcome a user to your site like so:
get '/auth/twitter/callback' do
  session[:admin] = true
  "<h1>Hi #{env['omniauth.auth']['info']['name']}!</h1><img src='#{env['omniauth.auth']['info']['image']}'>"
end
This will give them a personalized welcome and show their Twitter profile picture. If you want to continue using these details then you could save them in the session hash, like so:
get '/auth/twitter/callback' do
  session[:admin] = true
  session[:username] = env['omniauth.auth']['info']['name']
  "<h1>Hi #{session[:username]}!</h1>"
end
You could also use this as a way of authenticating users that you have stored in a database. Twitter provides all of its users with a unique id that can be a property of the User model. You could then look the user like so (this example uses the Mongoid syntax, but you should be able to make it work for your ORM of choice:
@user = User.where(twitter_id: env['omniauth.auth']['uid']

Updating Twitter

Once you’ve got a user authenticated with Twitter, you can theoretcially go on and start manipulating their Twitter account. What you are allowed to do depends on what you access the user grants to the application (you can select whether you want read only or read and write access for your application in the settings tab on the Twitter Developer site). Omniauth doesn’t actually let you manipulate a twitter account though. To do this you will need to install the twitter gem. There’s not enough room to go into using that now, maybe in a future post … but you might want to have a play around with it yourself in the meantime.

Frequently Asked Questions (FAQs) about Twitter Authentication in Sinatra

What is Sinatra and why is it used for Twitter authentication?

Sinatra is a Domain Specific Language (DSL) for quickly creating web applications in Ruby. It’s lightweight, flexible, and doesn’t follow the typical Model-View-Controller (MVC) pattern like other Ruby frameworks such as Rails. This makes it a great choice for simpler applications or APIs. When it comes to Twitter authentication, Sinatra provides a straightforward way to integrate with the Twitter API and handle OAuth authentication process.

How does Twitter authentication work in Sinatra?

Twitter authentication in Sinatra involves a series of steps. First, you need to register your application with Twitter to get your API keys. Then, you use these keys to request a temporary token from Twitter. Once you have this token, you redirect the user to Twitter to authorize your application. After authorization, Twitter redirects the user back to your application with a verifier. You then exchange this verifier for an access token, which you can use to make authenticated requests to the Twitter API on behalf of the user.

What are the prerequisites for implementing Twitter authentication in Sinatra?

To implement Twitter authentication in Sinatra, you need to have a basic understanding of Ruby and Sinatra. You also need to have Ruby and Sinatra installed on your machine. Additionally, you need to register your application with Twitter to get your API keys.

How do I register my application with Twitter?

To register your application with Twitter, you need to go to the Twitter Developer’s site and create a new application. You’ll need to provide some basic information about your application, and then you’ll receive your API keys.

What are the API keys and how are they used?

API keys are unique identifiers that are used to authenticate your application with Twitter. They consist of a consumer key and a consumer secret. These keys are used to sign each request your application makes to the Twitter API, ensuring that the request is coming from your application and not from a malicious third party.

What is OAuth and how does it work with Twitter authentication?

OAuth is an open standard for access delegation. It allows users to grant third-party applications access to their information on other services, without sharing their passwords. In the context of Twitter authentication, OAuth is used to authorize your application to access the user’s Twitter account.

What is a callback URL and why is it important?

A callback URL is the URL to which Twitter redirects the user after they have authorized your application. It’s important because it’s where you receive the verifier that you exchange for an access token. You need to specify your callback URL when you register your application with Twitter.

How do I handle errors during the authentication process?

Error handling is an important part of any application. In the context of Twitter authentication, you might encounter errors when requesting tokens, redirecting the user, or exchanging the verifier for an access token. You should have error handling mechanisms in place to catch these errors and provide appropriate feedback to the user.

How do I make authenticated requests to the Twitter API?

Once you have an access token, you can make authenticated requests to the Twitter API. You do this by including the access token in the Authorization header of your HTTP requests. The exact process can vary depending on the specific endpoint you’re accessing.

How do I ensure the security of my application and the user’s data?

Ensuring the security of your application and the user’s data is crucial. You should always use HTTPS for your application, especially during the authentication process. You should also store your API keys and access tokens securely, and never expose them in client-side code. Additionally, you should follow best practices for OAuth, such as using short-lived access tokens and refreshing them regularly.

Darren JonesDarren Jones
View Author

Darren loves building web apps and coding in JavaScript, Haskell and Ruby. He is the author of Learn to Code using JavaScript, JavaScript: Novice to Ninja and Jump Start Sinatra.He is also the creator of Nanny State, a tiny alternative to React. He can be found on Twitter @daz4126.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week