I am using HTTP authentication to sign_in and sign_out. It works great. However, I want to allow users to sign_up for a new account from my mobile app and then send that over using POST and in JSON format. What do I have to do to make this work?
I am using Devise for authentication for my Rails app.
You can POST an http-request with your username/password parameters to your login controller action (which could be as simple as requesting /login?user=foo&pass=bar), specifying .json format (using respond_to). You may need to include the CSRF, too. And I'm assuming here, since you didn't specify the mobile platform or post any code, that you've got the 'making the actual request' part down.
Related
I'm building an iOS app with Rails on the back-end.
The Rails application uses Devise for authentication and I want to use the same service for the authentication on the iOS app. Is there any way that after authenticating, keeping the session even after the app restarts, so that it goes straight to the content of the app instead of the login screen?
I've looked around, but haven't found a clear answer.
Thanks on advance!
One solution could be to extend the existing devise models and controllers to also handle a token based authentication system. Based on the request type html or json, the app can choose to authenticate a user either by the authentication token and email or a combination of username/email and password.
The authentication token could could be saved on the client side and reset only when the user logs out.
I was recently working on the same problem and found these sources to be extremely useful.
https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
http://www.soryy.com/blog/2014/apis-with-devise/
https://github.com/lynndylanhurley/devise_token_auth
I've been searching for a solid solution to this problem, and came across this SO question which kind of matches my predicament, but not exactly.
Currently I have my iPhone application authenticating with my Rails API via Basic Auth. It's just your simple, run-of-the-mill devise auth package. I then followed the instructions to set up omniauth-facebook for devise and got that working on the browser side.
The part I can't figure out how to do is how to send the token received on the iPhone side (via the Facebook iOS SDK) to the server. I want the server to check the users table to see if that facebook user has signed up, and create an account for him if he hasn't. Then, I was thinking the server would generate a random password and send it back to the client device so that I could keep my same basic authentication strategy. Is this the proper way to implement single sign on for a web app and iPhone app? How would one go about modifying the server side packages to support authentication via a token sent from the phone?
You may want to take a look here:
Open Source: Announcing devise-iOS For Simplified Auth
It looks like a relatively painless way to work with Rails / Devise and iOS. I definitely plan on using it in my next project.
Have you looked into making your app an Oauth2 provider?
I haven't done this myself, but after some digging it looks like opro and doorkeeper are two possible solutions to the problem.
https://github.com/opro/opro
https://github.com/doorkeeper-gem/doorkeeper
looks like opro works pretty well with devise:
#inside initializers/opro.rb
Opro.setup do |config|
config.auth_strategy = :devise
end
Definitely interested to see how this turns out for you
I think you have the right plan. We've done exactly this in our app and Web service.
The apps use a REST API, basic authentication over HTTPS, a server-generated password, and all of this is implemented without Devise. There's a method in the controller that all the API controllers inherit from, that is a before_action for all the API methods, and it calls 'authenticate_or_request_with_http_basic'
class ApiController < ActionController::Base
before_action :authenticate_api
def authenticate_api
authenticate_or_request_with_http_basic do |username, password|
# check server-generated password
end
end
end
So that handles most requests.
We also have a API controller action to register from the device once to get that server-generated password:
class UsersController < ApiController
skip_before_action :authenticate_api, only: [:register_fb]
def register_fb
graph = Koala::Facebook::API.new(params.require("access_token"))
profile = graph.get_object("me?fields=email,first_name,last_name")
# then go on to look up user if already exists, or create
# ... return server-generated password
end
end
The Web app, however, all controllers inherit from WebappController and use devise.
Thus we have two passwords on the User object (one for web, one for mobile) and a facebook ID as well as our own User id which is the one we use for authentication.
I am using Devise gem for web authentication in my Application.
Now i am about to write a mobile app for my Application which includes Sign in / Sign up process.
What is the correct way i should use to sign in a user and authenticate each call made by the user from the mobile app?
Which of the below strategy is correct? (i am not sure which method to follow to be more secure)
Note : You can view the above image in http://i.stack.imgur.com/I13uT.png (will be more clear)
FYI : I am using Titanium to develop mobile app and my backend server runs Rails app
Model #1 isn't secure, you aren't passing any sort of authentication on subsequent requests to validate that the user is still who they say they are.
What I'm presuming you really want to know is, what's the best way to verify the user is who they say they are, after logging in. I've answered this previously, Exposing Rails/Devise Authentication to iOS application and the same answer applies here.
Using token authentication in Devise will match model #2, and is also the most secure since you exchange the username/password for a token rather than having to store their username and password and reuse it with every request.
I'm not sure how #1 is secure at all since none of the subsequent requests are signed in any way. If someone knew the file structure of your app they could just access it that way, right?
With Devise, you can set an attribute on your User model to allow users to be authenticated via token:
class User < ActiveRecord::Base
devise :token_authenticatable
# there are other details and options on this, but this is the relevant piece
end
On each controller you can also verify that the user is authenticated by including before_filter :authenticate_user! at the beginning:
class PostsController < ActionController::Base
before_filter :authenticate_user!
end
When making requests from the mobile app, include the auth_token in the request so that the Rails app can authenticate before responding.
Beyond authentication, you may also be interested in something like CanCan to handle authorization as well.
I am developing an web app that will be used by iphone app. I use devise as authentication and i can create a new user, login as the user and when login is done it gives out
{"user":{"authentication_token":"xxxxxxxxxxxxxxxxxx","email":"sample#example.com"}}
but how can i change the password using json.
Most likely you will need to build an API for this, utilizing Devises JSON (Warden) to respond to JSON etc
reference to help point you in the right direction creating sessions with devise
Searching SO also yields
Ajax login with devise
I have created a simple API for a Rails application using token-based-authentication that supports User Log In and Log Out and a couple of other actions to update a User's status. I want this API to be used by devices running iOS. I have based my code on the example found here. In addition to allowing a device to login and update a User's status I would like new users to be able to Sign Up from the device. However looking at Devise's helper class I can't see any methods that support Sign Up, only Log In and Log Out.
Has anyone managed to implement Sign Up through an API? Are there any security issues with allowing this? How should I approach this?
Sign up from an iOS device is really just a (JSON?) POST to the User resource using a different format responder.
This data is passed in the clear from an iOS device, so make sure you use https on these routes if you're worried about security.