#241 Simple OmniAuth (revised)
Jun 02, 2012 | 11 minutes | Plugins, Authentication
OmniAuth makes it easy to do user authentication through a third party provider such as Twitter or Facebook. Learn a simple approach in this episode.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Awesome railscast Ryan! One thing... each time I log into my application (www.Meer.li), it logs me out whenever I close the browser. How do I save and retrieve the user with a cookie instead of the session, so the user will be logged in automatically when he visits the page the next time?
Hope you have a solution. Would really appreciate it!
Chapter 8 of railstutorial shows you how to do that: http://ruby.railstutorial.org/chapters/sign-in-sign-out#top
Pay particular attention to section: 8.2.1 titled "Remember me"
Great, thanks. I'll look into it straight away :-).
From looking at the source quickly -- it seems only the User model is slightly different as some logic from the controller was moved to it.
What's new in this episode?
What happens if the access token expires? The user should be not allowed to login again and should go through the Oauth process again, and the database should be cleaned for this user.
But he doesnt save the access token in this episode, only the provider and the uid
Great screencast, but I got stuck. Don't know how to set them ENV['TWITTER_KEY'] and ENV['TWITTER_SECRET'] variables. How do I set them? Is there a config file for that?
Would really be glad If anyone could help.
Quick and dirty:
Open .bash_profile in your favorite editor eg:
mate ~/.bash_profile
Add the two ENV variables like so:
export TWITTER_KEY=your_twitter_key
export TWITTER_SECRET=your_twitter_secret
Save and close the file
Either quit your terminal session & restart or reload it with:
source ~/.bash_profile
You are a stud!
Thank you!
If i deploy this application. will i be able to do the same change to a similar file on a linux server?
You can define them in the environment rb files. So, for dev, you can define them in the development.rb file. You can have a separate Twitter app, then, for production and put those keys in the production.rb file.
Actually, koriroys' answer is the better way to go.
Actually, I think your answer is exactly what I'm looking for. Working on a shared github app, I want all the developers to be able to run the site locally so they need to have access to the keys as well. Thanks a million!
Edit: for anyone new to Rails structure, these files are in config/environments.
How would one do this with devise?
Would also like to see how it all works with Devise. Devise now allows easily integration of OmniAuth but it's not clear the 30,000 feet view on this
The link to integration with Devise anyway is here:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
Yes, no example for Twitter is provided on the devise Wiki link and it takes a different approach than is provided in Ryan's earlier screencast with Devise and omniauth.
Twitter just worked and is brilliant.
This spurred me on to attempt FB.
I've been trying to FB working for 2 days now but no joy. All I get is No route matches [GET] "/auth/facebook".
Has anyone else had issues attempting to authenticate via FB?
Did you remember to put :provider in your route for the auth?
The Omniauth section of my routes.rb file looks like....
The strange thing is that there is no route listed for "auth/twitter" or "auth/facebook" - Ryan's notes say that Omniauth takes care of these. But in my case it seems that it's not taking care of the FB route.
Uh. I am embarrassed. School boy error. My problem was in how I had defined the provider in the omniauth.rb file.
I failed to spot an extra end statement in there.
Thank you Ryan, Nice!!, I was trying with Facebook that worked well, however when I tried the logout to login again with other Facebook account that didn't worked, is there a way to really logout from Facebook?
Thank you
Hi Ryan, really nice episode. Have you ever tried to provide omniauth for two models in the same application (e.g. Manager and Employee) for the same provider?
The problem lies in the routes used by omniauth. There's a single entry point for both the authentication route and the callback (per provider), so there's no way to differentiate between the two models.
One potential solution, could be to provide a parameter during authentication (e.g. :type => "manager") and handle it during the callback.
Do you know of any other solution?
I'm using Omniauth to authenticate at Twitter, but I have 2 apps registred with diferent names that I want to use depeding on the current locale(session scope).
So I need to change the provider key and secret defined at omniauth.rb file right before user calls auth/twitter( I was thinking to do a before_filter but auth/twitter is an external link to twitter and not a regular action) or a way to config Omniauth to define providers by locale instead of define for the entire application scope.
So how can I do that ? Any idea?
I think you can have a simple locale flag before calling auth/twitter. Something like this:
Rails.application.config.middleware.use OmniAuth::Builder do
case current_locale
when 'en'
provider :twitter, 'app1-key', 'app1-secret'
when 'es'
provider :twitter, 'app2-key', 'app2-secret'
else
provider :twitter, 'app3-key', 'app3-secret'
end
end
I see, but how do I intercept /auth/twitter ? it's not a common action and before_filters don't work.
Does anyone know if the uid returned by the provider remains constant all the time? Can it be treated like a primary key for the user,provider combination?
So the image that gets retreived from Twitter is the lowest resolution one. I am calling it in the user.rb like so:
def update_picture(omniauth)
self.picture = omniauth['info']['image']
end
How can I get one of the better quality image from Twitter?
Getting 401 when clicking your twitter authentication link ?
You're probably developing on localhost!
What to do ? Edit the callback url in your twitter app.
Problem? Doesn't like localhost urls with ports in it (possibly disliking everything localhost in general).
What to do, then ? Encode your localhost url in a url shortener!
Example: http://localhost:3000/auth/twitter/callback
=> http://goo.gl/O5v3O
I used Google's URL shortener (@ http://goo.gl/ ) - simply set the address given by your URL-shortener of choice as the value of "Website: " under "Application Details".
Done and done.
PS!: Ryan didn't explicitly say this, but to use the ENV['TWITTER_SECRET'] etc you can set these values under environments/{development.rb,production.rb} like so:
ENV['TWITTER_SECRET'] = 'ssssh it is a SECRET!'
I tried this solution and it didn't work for me. Perhaps I did something wrong.
I did however find this post, which suggested simply adding the callback url to your app on Twitter as
Couldn't get this working with pow though.
Using POW (and this example blog app) I got it working by setting Twitter callback url to....
http://blog-after.dev/auth/twitter/callback
If I'm setting the ENV['TWITTER_SECRET'] and ENV['TWITTER_KEY'] variables in the console how can I access them in the views?
So apparently when ENV is set in the console it's not available to the app.
Any suggestions on a way to set the ENV stuff securely? The code is hosted on Github so having the keys in the source code is a no-no.
You don't have to set them in your app. Do it in your .bashrc or .zshrc file.
This doesn't work for me. I still get a 401. I also tried http://127.0.0.1:3000/auth/twitter/callback to no avail.
Thanks!!! The url shortener advice helped.
Anybody tries to wire oauth though backbone.js?
In Twitter its important to check the "Allow this application to be used to Sign in with Twitter" option when you configure your app. If you don't have it checked, when you attempt to Sign in with Twitter you will always see the Authorization page. When checked you can automatically sign-in.
For the callback url, I found 'http://127.0.0.1:3000/' worked for me.
"Match" has been deprecated in Rails 4 and has to be replaced with "Get".
thx
The RailsApps project has a Rails 4.1 rails-omniauth example application with an in-depth OmniAuth Tutorial.
I am an athlete and I need this.
Wonderful tutorial, I'm loving your guides.
Wonderful tutorial, I'm loving your guides.