Authentication with AngularJs and Devise Rails, Do I need token system? - ruby-on-rails-3

I am creating an application based on Rails and AngularJS. I would like to implement an authentication system by using gem Devise.
I am wondering how to do it. I read some articles about attribute :token_authenticatable : I will have to put my token at the end of all requests I will send.
I have also read this demo project https://github.com/sectore/CafeTownsend-Angular-Rails
They have implemented a SessionService which can create and delete server session. (I suppose, I can use Devise for this job). In rails controler, they get session[:user_id] to know if user is authenticated or not...
My question : Do I need a token system or a cookies system to authenticated my requests ?
Thanks

If your server will be on the same domain as your client, ie: will only be expecting request from your angular client, and the client is hosted on the same URL as the server, then you should use cookies over ssl (for simplicity), EG:
Your site:
www.myangularsite.com/somepage
Your Server
www.myangularsite.com/someserverfunction
They both have the same domain.
However, if you plan on having your server side on a different URL, maybe as an API, then go with tokens, EG:
Your site:
www.myangularsite.com/somepage
Your Server
api.myangularsite.com/someserverfunction
or
myrubyapi.com/someserverfunction
The URL domain is different.

Related

Laravel 4 [API] how do i check if i already logged in from the consumer?

I've been creating API and consumer by following Simple API Development with Laravel from Aaron Kuzemchak. I got the problem after I success to auth via API from my consumer; I do not know how to check it, if the consummer already success logged in or not at the other pages...
For example, at the first; I show the login page, click the submit button to check the credentials via API. The login attempt is working, success to logged in and redirect to dashboard. But, if I haven't logged in and accessed the dashboard from URL, i got the dashboard :O
The API server and the consumer have separated machine and the database only exists at the API server.
Am I doing this right (with the flow for the API and Consumer) ?
At the consumer, how can I get to know if the user already logged in or not (after success attempt the credential)? (somehow? someidea?)
Thank you before... :)
This question is very confusing, probably because I haven't watched that screencast yet, but shouldn't Auth::check() be what you are looking for? It will return true or false depending on if the user is logged in.
Just to make sure:
You have a back end API built from the tutorial posted here: http://kuzemchak.net/blog/entry/laracon-slides-and-video
You're using HTTP Basic authentication as described in the above tutorial
You're building a (consumer) front end web interface for users on a separate server
Your consumer interface uses forms based authentication (a login form)
The backend API uses HTTP basic authentication (and the consumer sends an API key for the user with each request). As such, the backend won't keep track of a user being logged in. That means your consumer interface will need to do this.
You could use the Laravel Auth class for this normally, but your front end would normally have access to the database and the bundled authentication drivers could just check a username/password.
I'd say your options are:
Store details of the user in a session using the Session class (feels a bit nasty but simple)
Write an authentication driver and then use the Auth class (advanced but cleaner: http://www.karlvalentin.de/1903/write-your-own-auth-driver-for-laravel-4.html)
Just talk straight to the database using the existing Auth class and Eloquent

Create FTP User Accounts with Rails

Ok I'm not sure how to approach or explain this but I'll give it a try.
I'm developing a rails app on my mac using Devise for auth.
I would like to do the following:
When a user joins the site, the app creates an ftp user account with the same login credentials (email/password) they used to sign up. That way they can upload files via ftp using the root url of the site and their login credentials.
When the user updates their login credentials, their ftp user account needs to be updated with the same credentials.
Does paperclipftp or carrierwaveftp handle this? What would be the best way to accomplish this.
Thanks
Rather than setting up individual FTP accounts for each one of your site's users, this post walks through writing a controller action that handles the FTP authentication response instead, using your Rails users' credentials. It uses pure-ftpd and a custom authentication module to send an HTTP request with the credentials to your Rails app, which will then verify them by whatever means you'd like, and return the appropriate FTP response to the client.
I haven't tried it out, but I'm working on the same issue and this approach makes sense to me.

AngularJS: how to implement server-side or client-side authentication?

I want to authenticate an AngularJS app, it is running on top of Node.js and Express.js backend with Jade templates.
I thought of the following strategies:
1) server side authentication - store credentials in session variables and redirect the user to the AngularJS app, the problem: how to pass the credentials to AngularJS? (I can render those as Jade variables, but how can I read them with AngularJS?), also, how to handle session expiry ?
2) client side authentication - do the authentication with AJAX calls and get the credentials,
the problems: how to handle 'session' expiry and how to remember users so they won't have to login every time the app starts ?
any insights may help.
Setting up authentication for a Angular.js application isn't any different then setting it up for any other website. You post your username and password to the server and it will set a session/cookie if your credentials are correct. To get data (in your case crdentials) from the server you use the same techniques you always use with Javascript. Xhr, websockets, render values in a text field, ...

Multiple authentication schemes with Devise and Rails 3

This is probably a common question, but I haven't seen any complete answers to it anywhere:
I have an Rails 3 app that is using Devise for authentication on the web and is working fine. All actions on all controllers are authenticated and the routes are all restful. Users get redirected to a web page to enter their username and password and then can access the resources.
Now I need to add an API to the system. Most of the controllers/actions will be shared between the web and API users, but the API users will have a different authentication scheme (API keys perhaps).
So, if a web user goes to
/projects/1/users
to see the users on the web, an API user should go to
/api/v1/projects/1/users
to see the same thing with a parameter like APIKey=abcd.... either in the header or params to allow authentication.
I know the solution is around overriding the SessionController and the Routes but can't find a detailed answer about this anywhere.
You might be able to achieve the same results by using Token authentication:
http://rdoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable

How do you make rails 3 work as a backend for mobile apps with support for session_id's in the request?

I am trying to build a rails 3 back-end for a mobile application. However, I am new to creating rails 3 apps.
Users will need to have a session on the server, but I have no support for normal cookies, so I would need to send a session_id along with every request.
What kind of authentication system should I use in rails 3, is there a gem?
I have read that in rails 2 it was possible to set the session_id from the URL, but that this function is stripped from rails 3 due to security concerns. Is this even true? If there is a way to do this, I am very interested, despite the possible security holes.
Usually I'd use HTTP Digest authentication to solve this problem. Most of the Rails authentication plugins (such as Authlogic, probably Devise) will support HTTP Basic or Digest authentication though a plugin. In this way, you don't have to worry about expired cookies and the like.
You can also pass an api_key parameter instead of a session id.
In many cases I've used an api key as the HTTP Basic username. This gives clean URLs and session-less authentication.
The security problem you're probably referring to is Cross-Site Request Forgery. It is indeed a real problem. Its why you hide actions with side effects (create, update, destroy) behind forms with a CSRF token. Otherwise a malicious link can perform unintended actions to a site that you're already authenticated to without needing to know your credentials.
As long as your API key isn't easily discoverable by anyone in an automated fashion, the risk should be minimal.
Update
A small update: Devise no longer has authentication_token as its implementation was deemed too insecure. A good alternative is Brian Auton's suggestion.
The summary of his method is that he generates an authentication_key AND authentication_secret in a separate model. You then authenticate by sending both your key and secret, if a match is found you are temporarily signed in as a user.
In your application controller this looks like so:
class ApplicationController < ActionController::Base
before_filter :authenticate_from_token
protected
def authenticate_from_token
if current_token.try :authenticatable
sign_in token.authenticatable, store: false
end
end
def current_token
AuthenticationToken.find_authenticated({
secret: (params[:secret] || request.headers[:secret]),
secret_id: (params[:secret_id] || request.headers[:secret_id]),
})
end
end
The authenticatable of the token in this case is a User model, or any other thing that has been made authenticatable (the tokens are polymorphic). As you can see it can easily be made to work with Devise.
I like this method a lot and have implemented it in a recent API. Do read up on it on his website.
Old answer
Outdated answer, kept for reference to older versions of Devise: Devise has a 'authentication_token' column which I can use for authenticating a user. I could have a login API method which I will send a username + password too, then get the token back and store that locally to sign all my other calls with. It basically is a cookie system, but one that is directly supported by Devise.
On top of this I could re-generate the token on either every call or on every 'session'.