Can't understand scheme of creating API with Devise, RocketPants, Doorkeeper - ruby-on-rails

I was developing website and decided to separate back-end(rails) and front-end(angularjs). All went good until I tried to implement authenticating over JSON. I've found tons of material on how to implement it with devise, or with doorkeeper, but I can't understand how to put it together. (API is implemented with RocketPants)
From what I've realized, from front-end I should send login and pass on init, getting back authtoken (step 1). Then on every call I should send authtoken with other data (step 2)
On step 1: Doorkeeper redirects_to sign_in page. Should I modify controller in way that it should come to controller, which would handle authentication (by using warden.authenticate!) ? And how does Doorkeeper know that I'm logged in since that moment? (for giving me authtoken)
On step 2: Authtokens are individual per user and per application, which uses API, right? So I should somehow specify, from which application request comes, shouldn't I? "
Note: Backend is going to be API only, so everything should be handled by JSON requests. But how I modify available applications then? One more custom controller over Doorkeeper?
Thanks in advance, I hope, I'm not the only one with such questions =)

Related

How do I authenticate using Devise in a Rails REST API App?

I'm creating a Rails app which have both a GUI part, and a REST/JSON-API.
The REST/JSON API is fairly simple, and the controller returns data like this:
def get_players
#players = Player.all
render json: #players
end
The GUI part of the app is using Devise for authentication, and it works fine.
Now I want to add authentication for the REST/JSON Api too, how do I do that?
Also, how do I test the REST API using curl when the Authentication is added?
---- edit ----
as it turns out, Devise wasnt necessary in this case. A home-cooked token-authentication method works for now. (token created when Player is created, and returned on correct e-mail/password combo).
After getting a few tips, I found a number of great sites. There are several ways to do this, however I don't know which one is best, but these sites help a long way:
https://github.com/lynndylanhurley/devise_token_auth (An extension to
Devise)
https://labs.kollegorna.se/blog/2015/04/build-an-api-now/
(Manual way)
Token based authentication for Rails JSON APIs (SO Question)
Rails API : Best way to implement authentication? (SO Question)
Rails API : Best way to implement authentication?

Why using an authentication_token instead of the normal authentication process?

I have a Rails web application, and I want to build a JSON API as well so I can have mobile applications bound to it.
I've been reading a lot about it, and I don't get it why so many people prefer to activate authentication_token authentication instead of the normal authentication process that Devise offers us.
So, the question is: why use authentication_token ? Any performance reason ? Any security reason ? What is the best way to authenticate through an API ?
authentication_token is basically used to authenticate user from outside
i.e. say you sent user a email containing the activation link containing the token, so when he clicks the link, he directly gets logged in.

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

Security in angular.js with Ruby on Rails

What is the best way to make authentication?
on frontend I use Angular.js
on backend: Ruby on Rails
Rails app using as API for my frontend.
UPDATE:
This is will be single page application.
Frontend wiil be developed in Angular.js, backend in Ruby on Rails.
In ideal I want to build backend as collection of resources returned in json.
I search best method of security implementation.
When user open the app I need to check if user authenticated.
If not - go to login page,
If authenticated - open that he wants and return needed resource from backend.
I think that I need to store auth token on the client side.
What is the best method to generate it, or maybe Rails already generate it for me?
I don't know Angular.JS at all but I will try to provide you general information on rails that you can use with any Javascript Framework.
For authentication, you just needs:
A model for users
a controller which handle login, this method check user login/password, create a session object with all information needed (session is stored on server side and a cookie is used on client-side to associate each request to a session)
A controller for handling logout which basically only destroy the user's session
You have a good implementation in the rails tutorial here, or you can find several plugins (authlogic seems to be the recommendation of stackoverflow usershere).
Then, there is few differences between handling authentication with static html pages or with AJAX:
A HTML request will send login and password to the controller, which will automatically redirect it to another internal page once the session create
In AJAX, the javascript on client side should send an ajax request, look for the answer by the server (success / failure) and launch adapted actions (message if failure, redirection if success)
In both cases, the important thing is to check that the user is authenticated at at each controller otherwise anybody would be allowed to launch action or access internal information.
I'm trying to do something similar and I found this example app which has been very useful to get me going in the right direction: https://github.com/karlfreeman/angular-devise
Also checkout further discussion about it here: https://github.com/karlfreeman/angular-devise/issues/1
And here's another repo which takes a slightly different approach: https://github.com/colindensem/demo-rails-angularjs
I ended up borrowing ideas from all of the above. Here's a working demo if anyone's interested: https://github.com/jesalg/RADD

Omniauth: How to set authentication provider details at runtime

I have a rails app that is accessible from 2 domains. Facebook requires me to register a facebook app for each of these domains and gives me credentials for each. With Omniauth I can only specify one set of credentials that is set on application startup. However, I would need to supply FB with different credentials depending on the host of the request.
There are 2 problems here:
How can I change the Omniauth credentials for facebook at runtime?
How can I intercept the call to facebook, check the domain and set the credentials accordingly? A before filter will not work, as Omniauth uses Rack Middleware.
Any suggestions are highly appreciated!
Copying the answer from the comments in order to remove this question from the "Unanswered" filter:
I solved this myself now. The problem was that the fb strategy calls
back to fb a second time to get an access token. In that second call
the wrong credentials were used (the ones set in the initializer). So
I had to patch the OAuth2 strategy so that it calls through to the
rails app again, to set the runtime credentials for that second call.
In the call back, which normally only handles the response form
Omniauth, I set the credentials and return a 404 unless
request.env["omniauth.auth"] is present. That works fine but has some
side effects for apps without dynamic providers.
The problem is now, that even if an application doesn't want to set the credentials at runtime, it has to add a condition to the callback like if request.env["omniauth.auth"] to avoid the callback code being executed when it is called the first time. The solution is probably to add a parameter to the Omniauth builder like :dynamic_provider and only call through to the app if it is set.
~ answer per Nico
This question is fairly old but still relevant. Nowdays it is also possible to set provider details dynamically during OmniAuth's Setup Phase.
For example:
Rails.application.config.middleware.use do
provider :example,
setup: ->(env) do
env['omniauth.strategy'].options[:foo] = env['rack.session']['foo']
env['omniauth.strategy'].options[:client_options][:site] = Something.dynamic('param')
end
end
Source: https://github.com/omniauth/omniauth/wiki/Dynamic-Providers

Resources