Puzzling over my routes.rb file - ruby-on-rails

I am writing a Rails app that I partially inherited. There is a snippet of code in the routes.rb that I'm trying to puzzle out and can't find anything in the documentation.
authenticate :users do
resources :authentications
end
What does this do and why is it needed here? I'd never seen the authenticate used in this context before. There are resources called users and authentications in the file, and I am using Devise+OmniAuth for authentication.

As seen here in the Devise Docs, it allows you to add authentication at the router level rather than at the application level(aka controllers, essentially).

Related

Using devise_token_auth with jsonapi-resources

I am trying to use devise_token_auth with jsonapi-resources. I have it set up where I can create users and sign in, but I cannot figure out how to access a controller that has needs to authenticate a user first. Here is my controller that I am trying to require authentication:
class FriendsController < JSONAPI::ResourceController
include DeviseTokenAuth::Concerns::SetUserByToken
before_action :authenticate_user!
end
When I try localhost:3000/friends, I get a 401 "Authorized users only." error, so I think it works. I think my main problem is Im not sure what to do with the access-token I get when I sign in. I have tried setting it in the header in my request, but still get the same "Authorized users only" error.
Better a late answer than none... devise_token_auth and jsonapi_resources work pretty well for me in a test setup. But, you need to set the request header correctly. It is not enough to transmit the "auth-token" header, you also heave to transmit the "client" token, the "uid" and the "token-type" header as well. Although I'm not entirely sure if the latter is actually required.
Devise token authentication is quite independent of jsonapi-resources. If you can get token authentication working (as explained in this answer, for example: Custom devise api token auth) you can simply extend your controller (or your ApplicationController) with the authentication concern and it should behave as a normal Rails controller would.

How to process requests for certain sub-domain(s) in Rails?

For example, I want my project link to look like http://blog.example.com. How can I make that kind of route in Rails 4? And how it can interact with controller?
The following stuff didn't work for me.
resource :article, constraints: {subdomain: 'blog'}
Your code is acting as a type of filter, so only requests already utilizing the subdomain 'blog' will invoke the route. You need to ensure that the web server itself is also setup to handle that subdomain and point it to your application.
Edit: Try checking out this post for further clarification (if you're on your local environment). https://reinteractive.net/posts/199-developing-and-testing-rails-applications-with-subdomains

Learning Doorkeeper

I am trying to set up APIs for a broker application (users can buy/sell items when they are logged in). Developers should be able to build on top of my app. Aiming to use Devise and Doorkeeper gems. I have already set up Devise (so my users have to log in/log out of their accounts). But I am having problems understanding how to use Doorkeeper gem.
I have read through the following so far
RFC 6749
Doorkeeper wiki
Tutorial for Oauth 2 on Rails (Wasn't very helpful as I got stuck while following the steps)
Oauth with Doorkeeper railscast
Problem is - I still don't quite get how to set up my servers, create pages which other developers can register their app on, attain their keys,etc.
What am I missing, is there any comprehensive tutorial which I can learn from to set up my API for developers to register their app on, login on behalf of users and execute buy/sell orders?
Registering applications
Doorkeeper comes with integrated controllers/views to manage oauth applications, request access tokens and authorizations.
If you installed and configured doorkeeper correctly, these routes are defined in your rails application :
GET /oauth/authorize/:code
GET /oauth/authorize
POST /oauth/authorize
DELETE /oauth/authorize
POST /oauth/token
POST /oauth/revoke
resources /oauth/applications
GET /oauth/authorized_applications
DELETE /oauth/authorized_applications/:id
GET /oauth/token/info
(See https://github.com/doorkeeper-gem/doorkeeper#routes)
When you go to /oauth/applications, you can add or remove oauth applications. This might help for your problem
create pages which other developers can register their app on, attain their keys
However, these are made for backend or quick setup purposes. It's not recommanded to use that in production. You can create controllers/views based on these to start with.
If you want to learn more about customizing these controllers/views, check these links :
https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes
https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-views
Setting up your API
If you don't use the Rails API mode, I recommend you use the grape gem, which is a framework for building APIs in Ruby. You can then mount your Grape::API application to a route of your Rails application.
Then, when users will register their applications, they will be asking for access grants (authorization code) for each individual user of their own applications. The /oauth/authorize routes are exactly that. They will use an OAuth2 client to build the authorize_url properly and setup their applications.
All this flow is compliant with the OAuth2 framework (RFC 6749). But as you said; you read it, so you should understand what's going on behind the scene.
All you have to do is provide your API endpoints :
# in your API class that extends Grape::API
post 'orders/:id/buy' do
# authorize a specific scope, this is just an example,
# this might not suit your app design
doorkeeper_authorize! :buy_order
# you can get the resource owner id with and other token infos,
# or put that in a helper method
current_user = User.find(doorkeeper_token.resource_owner_id)
# buy order logic goes here...
end
post 'orders/:id/sell' do
doorkeeper_authorize! :sell_order
current_user = User.find(doorkeeper_token.resource_owner_id)
# sell order logic goes here...
end
Hope that can help!

Should admin be a subdomain or a namespace?

When would you use a subdomain over a namespace? i.e. http://admin.foo.com VS http://foo.com/admin
Alternatively, I also like how api.foo.com looks VS foo.com/api. I also find, subdomains a bit tricky to set up.
Mounting another app inside a folder or a subdomain is no big deal with Web-Servers, but if your Rails app contains both the /admin and normal applications it gets trickier to serve one as a subdomain.
Thankfully the Rails router is very flexible in this regard and supports both scenarios rather well.
TLDR: Rails supports both ways through the routing engine and at this point it comes down to personal preference (although I suspect the subdomain option will not play too nicely with path helpers)
/admin Routes
To achieve the /admin routes, Rails supports the notion of namespaces in routing. So having a /admin area in the Rails app you just write this in your routes.rb like this:
namespace :admin do
resources :users
resources :posts
end
You then put the controllers for the /admin area in controllers/admin/.rb and the class has to be prefixed with Admin (like Admin::PostsController).
Since most application's Admin area will most likely interact with the Models from the normal application it's probably safe to say doing namespacing is the most convenient way.
Subdomain Routes
But namespacing can also be used with subdomains as it turns out:
The Rails router can define constraint blocks and define the namespace inside these blocks.
So if you want to host the namespace from above only in the admin.example.com subdomain you can do this:
constraints(:subdomain => /admin/) do
namespace :admin do
resources :users
resources :posts
end
end
(I didn't know about the contraints feature but this blog post seems to explain it quite well)
This obviously requires you to configure the web server in a way that it serves admin.example.com and www.example.com to the same Rails application.
I am not sure if session (achieved through cookies) is carried over but I guess you can figure this out.
I think the other answer addressed the practicality issue, but purely from a security perspective:
Putting admin in a subdomain is recommended in the Rails Security Guide because it is more insulated from an XSS attack:
Put the admin interface to a special sub-domain such as
admin.application.com and make it a separate application with its own
user management. This makes stealing an admin cookie from the usual
domain, www.application.com, impossible. This is because of the same
origin policy in your browser: An injected (XSS) script on
www.application.com may not read the cookie for admin.application.com
and vice-versa.
So from a security perspective, putting admin in a subdomain may be safer.

Help with rails restful authentication

I just installed the restful authentication using this plugin and when I go to localhost:3000/login
i get this error
NameError in SessionController#new
uninitialized constant
SessionController
Any ideas? please help.
First of all, if you're just getting started with Rails authentication, I'd highly recommend you use Authlogic. Restful Authentication had its time but it generates a lot of code that isn't always clear and it's pretty tough to extend.
If you're set on using Restful Auth, make sure your Session controller is created, the routes are present, and the actions within the session_controller.rb are created.
This was mentioned on the Railscasts site...
Try this (pluralize sessions):
map.resource :session, :controller => 'sessions'
Restful auth had its day. You'll be better off with authlogic. I wrote a little post here on authlogic basics.
http://blog.platform45.com/2009/09/30/user-authentication-with-authlogic

Resources