I've built a Rails app with a simple API. I'm using Devise for authentication. I'm trying to work out how to log a user into the rails app from my iOS app so they can retrieve and post data. I've been searching all day for the best way to do this but most info is outdated (using Devise's deprecated token_authenticable solution.
I've got my rails app. I've got my iOS app. I've written my API. How do I connect the pieces together?
Thanks
Details:
My app allows users to fill in a form and have that data sent to the server. In another section of the app the user can view the data they have previously submitted. When the app first launches the user should login to their account so that the data they post is associated with them and they can only view data they have previously posted. It's quite a simple app. How do I log them in so that I can tell the API to only return their data.
Set your server up to use SSL, then the communication to the server are secure. Post the userID and password to the server in an SSL. You can pass that information on each access to the server.
If you want to pass the UserID/Password only once then you can setup a session with a cookie but you will need server support for the session and timeouts.
What you need to define is how secure you want the authentication to be. That is who are you defending against? A friend, an enemy, a government? Define the value (in $) of a security breach. Defend to this level.
Related
This is my first heavy task as a junior Rails dev so it might be a trivial. All the described applications work as microservices and my application can also be considered so
Rails app explanation
Rails 7
Ruby 3.1.2
Devise (API and web)
I've got Rails 7 app which is a single page dashboard with Devise to register/login users and show data from 3rd party API (let's call it main PHP microservice). User registration takes place outside the user's control via POST request from main PHP microservice to my Rails app. To login to the Rails app user needs to provide received SMS code each time. I need to implement that peace of login flow.
Problem explanation
The logging mechanism must include two factor authentication (2FA) which is handled by the main PHP microservice that sends an SMS (text message) with a code to login.
From a Rails side, when credentials (login/password) are correct a POST request is sent to the main PHP microservice to trigger 2FA. The main PHP microservice sends an SMS code (text message) to the user's phone which he later has to enter inside my Rails application.
So in a bullet points, the login flow inside my Rails app will be:
User provides login/password
If authentication credentials are correct, redirect to new window where the user must enter the SMS code they received on their phone
Login to the app when provided SMS (text message) is correct
3a. Trigger new 2FA process via POST request to the main PHP microservice and allow user to enter new code
What I was trying to use here is gem devise-two-factor but it use database to mark if 2FA is correct or not which I cannot use because one of the requirements of my ticket is not to use a database to determine whether 2FA is correct or not:
the gist is, username / password, and be able to set a cookie or add it to the session with the 2fa status for that session
Because a lack of knowledge, I cannot argue with this requirement and believe me, I tried.
Questions
From what I have read, to meet these requirements the safest way is to use an encrypted cookies. How to inject that to make it work with described devise login flow?
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 am using devise in my rails app. There is an ipad app that connects to the this rails app and authentication is done using token. (devise token_authenticatable).
For sessions, I using the default cookie store. My session_stor.rb looks like this,
Ap::Application.config.session_store :cookie_store
Now say I need to store minor data for the ipad user in session, where is it stored? Say in my controller I am doing,
session['last_search'] = search_key_word
Where is this data stored? I am asking this because on cookie based session store, usually session data is stored in browser. I couldn't find any resource that explains what happens in case of a non browser client that uses token for authenticatication.
I suggest saving the history locally in the iPad's app itself. You can create a table "search_history" that stores the recent 10 keywords. Or you may cache it if you want (also on the client side).
Say I have a big rails app running at https://www.acme.com and I want to make a new rails app running at https://billing.acme.com. The point of breaking this billing service out into it's own rails app is:
want to be able to deploy changes to it independent of releases to the main www rails app
want to stop adding code to our main www rails app because it's already so big
When a logged in user clicks over to https://billing.acme.com what's the best way to identify the logged in user? Read the cookie because it's the same domain just a different subdomain? Send over a token because reading the cookie is a bad idea?
You may be interested in Rails Tutorial for Subdomains with Devise.
As for sending a user_id back and forth, you may want your subdomain app to access your main app through its API.
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.