Should admin be a subdomain or a namespace? - ruby-on-rails

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.

Related

How do I hardcode a route root for Url.Action when generating a confirmation link

My Asp.net core web app can generate a confirmation link successfully using
string confirmationLink = Url.Action("SetPassword","Account",
new
{
userid = userMaster.Id,
token = confirmationToken
},
protocol: HttpContext.Request.Scheme);
This roots the route using the root of the current controller's page.
Now I have moved out the logic to a web api and I would like to use the root of the calling page in the Url.Action statement in the webapi.
I want to achieve following points.
a) get the root of the current page and
b) having passed that root to the webApi how do I seed Url with it so that it is available to Url.Action?
Workaround: I am generating the confirmation link as a simple string.
string confirmationLink = ${this.config.p_ConfirmationURLRoot}/{this.config.p_ConfirmatonURLController}/{this.config.p_ConfirmationURLAction}?userId={ userMaster.Id}&token={ confirmationToken}";
This does not resolve the questions posed above, but if like me your end goal is a working link that may be used else where, this approach will satisfy that requirement.
It sounds like you're trying to work with request-routing for a front-end application using the routing of a separate API. This isn't a use-case for the ASP.NET routing systems; they are only interested in routes within the application domain. The front-end application has its routes and the API has its routes: both are completely separate concerns.
This is a good model, one you want to work with rather than against. The front-end application should be free to change its URLs without requiring changes in other applications.
By all means, have a separate API to perform logic like user-creation and validation of security tokens, but these are not concerns which should be intermingled with front-end routing.

How do I set up a Rails page as a subdomain of another site?

We're trying to create pages in our Rails app that will eventually live on a subdomain of another partnering site. This would be like StatusPage, which allows users to create a status page with their account on the StatusPage site and then attach it to their own subdomain (e.g. status.usersite.com).
For example, if we wanted one of our pages (www.oursite.com/users/bobsplumbing) to be a subdomain on another site (ourservice.bobsplumbing.com), how would we go about it?
If it's useful info, we use Heroku to host the Rails app and we also utilize Route 53 and Cloudflare.
From your example I understand that you want to have multiple web apps since that would be your customer domain and your page will redirect to that page.
You will be better off to do NGINX (or whatever you use) redirects since they are faster and will take less time, being cached by the browser after the initial load.
To answer your question you can add this code to your routes:
sites = %w(bobsplumbing catsandboots)
sites.each do |name|
match "users/#{name}" => redirect("https://ourservice.#{name}.com")
end
You can also have a look at apartment gem.

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

Rails 3 custom domains for users on Heroku

I'm looking to set up custom domains for users. Much like Tumblr does.
I understand that the user must point their A record to an IP address. I found some information here: Custom domains in a Rails App
Can someone give me an example of this with a Heroku/Rails 3 setup? Is it even possible?
If you setup a wildcard DNS to point to your main app, you can use the :subdomain in config/routes.rb to handle your business logic.

Puzzling over my routes.rb file

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).

Resources