17

I have a rails 3.1 application that uses Devise for Authentication with a simple User model with email,password etc. I need to be able to authenticate from an iphone application. How do I expose this functionality? Broad answers are fine as I am not sure what my options are.

Undistraction
  • 42,754
  • 56
  • 195
  • 331
  • All devise controllers respond to json and xml, making a REST interface quite possible – zsquare Jan 12 '12 at 14:23
  • 2
    Honestly, I have the exact same problem. I understand REST, and my API is working well. But I cannot grasp the concept of logging in from the iOS device. (I'm using RestKit as a framework, if that helps). Can someone please go through the steps necessary to get the iOS devise to authenticate with the rails app, and then continuously call the REST calls to get the information? How do you store the session? Can you? Do you need to pass in the user credentials with ever call? Can you use a token of some sort? How do you format the call to get the info? Help would be great for me too!! – Ethan Mick Jan 12 '12 at 16:53
  • @Wayfarer Exactly. I'm thinking the Web Service needs to pass some kind of token to the device once it has successfully authenticated which the device can use to identify itself with any communications, but I'm not sure how this would work in practical terms. Obviously the User model could store some kind of unique token for each user that is shared after authentication, but I'm not sure of the mechanics of serving that up. – Undistraction Jan 12 '12 at 17:24

1 Answers1

11

The fastest way would be to simply enable http_authenticatable and pass the username and password through HTTP Basic Auth. While that's the easiest way, it means you have to store the users password in plaintext and send it along with every request you make.

A better option is token authentication, you can pass it through parameters or HTTP Basic Auth (in which case you can set the password to "X" and the token to the username). The advantage to this is that you can just use the username/password initially to get the token and then use that for any further authentication.

The simplest way to do token authentication with the minimum amount of code would be to enable HTTP authentication in Devise and setup a new controller that requires the user is logged in and all it does is output the result of reset_authentication_token. Once you have the token you would then pass that to any future HTTP authentication requests to log them in.

Zachary Anker
  • 4,500
  • 21
  • 19
  • Does enabling http_authenticatable then drop down the horrid Username/Password field if you try and log in from the website? I still need users to login via the website, and through a clean interface. – Ethan Mick Jan 12 '12 at 18:22
  • @Zachary Anker Thanks for your answer. Can you confirm I am understanding this right... A device would hit http://somesite.com/users/sign_in, passing username and password as form params of a POST request. Rails would then check these details and if correct would return a token. The device would then store that token and use it in any future communications. So where does rails get the token from? Does it generate a unique token for each user. Does the token expire? – Undistraction Jan 12 '12 at 18:25
  • @Wayfarer It shouldn't. As long as it's a navigational format such as HTML it shouldn't popup an HTTP authentication dialog. If you didn't want to have it ever show up, you could also implement the password check yourself in the controller that returns the authentication token. – Zachary Anker Jan 12 '12 at 18:29
  • 1
    @1ndivisible You would need to write your own controller that handles it, /users/sign_in/ would be the Devise controller which won't return the token. Devise handle's setting the token and generating an unique one. It does not expire unless you add something custom to handle it. You would call `user.reset_authentication_token!` and then use `user.authentication_token` to get the authentication token. – Zachary Anker Jan 12 '12 at 18:31
  • @Zachary Anker So authenticating from a device would hit a separate URI eg api/users/sign_in/? – Undistraction Jan 12 '12 at 18:40
  • @1ndivisible Your iOS authentication would need to hit a separate URL and call a controller you wrote, correct. – Zachary Anker Jan 12 '12 at 18:41
  • With your push in the right direction, I think I have it working! Thank you! – Ethan Mick Jan 12 '12 at 19:40