How do I manage sessions in a hybrid Ruby/GWT system? - ruby-on-rails

I currently have a Ruby on Rails system, and there are plans to port it to GWT. Before we do this, the powers that be want to have a proof of concept with part of the site being written in GWT to show that GWT can use and display the current content. The flow of data in the GWT portion of the system is as follows:
Client sends an RPC call to the GWT server
Server receives RPC call, then makes an equivalent Ajax request to the Rails system
Server generates a Java object from the result of the Ajax request, passes it back to client
The issue I'm running into now is managing user session data across both systems. We only have 1 Tomcat instance, and that has its own type of sessions, and then our Ruby system uses ActiveRecordStore to store session data in the database.
The problem here is that when the Tomcat system talks with the Ruby system, if the GWT client has made a login request, the last user to log in from the GWT system has all outgoing Ajax requests being performed in the Rails system as if they're the current user since the Tomcat system looks like a single client to Rails.
Anyways, how can I make it such that if a user begins a session with the Tomcat system, the Ruby system will be aware of this and have an equivalent session so that even though the Tomcat server is a single client to it, the Rails system is aware of the fact that many different users are communicating with it from that single client.

I think the best way to solve this would be to use cookies instead of a database to store the session. Rails supports this natively, actually it's the default cookie store for some time now. The cookie itself is signed by a server secret to prevent user tampering. I think the Rails implementation uses Ruby marshaling to dump/load the data so you might have to implement it in Java, or you can implement your own cookie manager on both sides using the same idea.
It is also possible to just use the Ruby code from JRuby in your Java application.

I don't know about RoR, but in most web technologies sessions are maintained using cookies. If you preserve the cookies (for a given user) across multiple calls from your Java server to your RoR instance, you should be all good.

Related

How to make common authentication between 2 server - Rails & Django

the service I'm developing consists of chrome extension & web application.
For it I'm trying to create 2 server:
web application server (build by Rails)
API server(build by Django) to receive requests from chrome extension and process user data.
Those application use same database, same user information.
My question is how to authenticate users -- in Rails app, users can sign-up and sign-in via form. But in API server, how to authenticate users?
One solution might be JWT authentication, user get JWT token from Rails server and send token to Django server, and Django server authenticate by JWT authorization.
Is that best practice -- or simply sending username & password is better then this?
Thanks
I honestly believe that attempting to combine these two web platforms is not the best idea. You can read feedback from a similar question here, but basically attempting to combine rails with Django will lead you down a serious rabbit hole where both Rails and Django are going to be expecting to handle the authentication. You can potentially use a different, more simple Python framework, but I think you can potentially achieve the same overall goal with a single Rails application.
If project specifications require Django, then you can potentially try the latter option of username & password to do a database read, and then manually create a JWT functionality. I think it would be really really difficult though to use many of the built in, or even open source solutions, that Django provides, which is why Django could be overkill.

How do you create an API server based on data from an existing Rails/Postgres web application?

I have an existing web application that's developed with Ruby on Rails and PostgreSQL. I need to create a mobile application (and possibly a separate web application) using the data from that web application, so I'm looking to create an API server. Is it possible to do this without altering the source code from the original Rails/Postgres web application?
Any ideas on the best way to do this? Or can someone point me in the right direction on what to research?
To connect a new application hosted on Heroku to a PostgreSQL database hosted on Heroku just push your new application to Heroku as normal.
Then, under Settings on your new application dashboard, go into Config Variables and add a new config for DATABASE_URL. Put the value of the url for your existing database.
Your new application will need to be under the same account as your existing application. Heroku doesn't allow you to connect across accounts.
You probably want to take a look at this question for additional details.
Sounds like essentially you want to have two applications connecting to the same database offering the same methods, but respond in different formats (html vs, for example, json). One way of doing that relatively easily might be pushing another api only Rails app to heroku that connects to the same Postgres database (which was mentioned in the comments), but you would have to figure out how to handle authentication differently for your API end points. This depends on whether you are exposing these end points to the public or to something like a mobile front-end. You may want to switch to token-based authentication if you were formerly using sessions on the web-app. Once you implement secure authenticatoin for your api routes, all you have to do is make sure your methods, instead of rendering erb or haml templates, are returning raw data consumable by your intended client.

Design pattern: ASP.NET API for RPC against a back-end application

I'm designing an API to enable remote clients to execute PowerShell scripts against a remote server.
To execute the commands effectively, the application needs to create a unique runspace for the remote client (so it can initialise the runspace with an appropriate host and command set for that client). Every time the client makes a request, the API will need to ensure the request is executed within the correct runspace.
An (over-simplified) view of the flow might look like this:
Client connects to Web API, POSTs credentials for the backend application
Web API passes these credentials through to the backend app, which uses them to create a RunSpace uniquely configured for that client
Web API and app "agree" on a linked session-runspace ID
Web API either informs client of session-runspace ID or holds it in memory
Client makes request: e.g. "GET http://myapiserver/api/backup-status/"
Web API passes request through to backend app function
Backend app returns results: e.g. "JSON {this is the current status of backup for user/client x}"
Web API passes these results through to remote client
Either timeout or logout request ends 'session' and RunSpace is disposed
(In reality, the PowerShell App might just be a custom controller/model within the Web API, or it could be an IIS snap-in or similar - I'm open to design suggestions here...).
My concern is, in order to create a unique RunSpace for each remote client, I need to give that client a unique "session" ID so the API can pass requests through to the app correctly. This feels like I'm breaking the stateless rule.
In truth, the API is still stateless, just the back-end app is not, but it does need to create a session (RunSpace) for each client and then dispose of the RunSpace after a timeout/end-session request.
QUESTIONS
Should I hack into the Authentication mechanism in ASP.NET MVC to spin-up the RunSpace?
Should I admit defeat and just hack up a session variable?
Is there a better SOA that I should consider? (Web API feels very neat and tidy for this though - particularly if I want to have web, mobile and what-have-you clients)
This feels like I'm breaking the stateless rule.
Your application is stateful - no way around it. You have to maintain a process for each client and the process has to run on one box and client always connecting to the same box. So if you have a single server, no problem. If you have multiple, you have to use sticky session so client always comes back to the same server (load balancers could do that for you).
Should I hack into the Authentication mechanism in ASP.NET MVC to
spin-up the RunSpace?
If you need authentication.
Should I admit defeat and just hack up a session variable?
No variable, just use plain in-memory session. In case more than 1 server, use sticky session as explained above.
Is there a better SOA that I should consider? (Web API feels very neat
and tidy for this though - particularly if I want to have web, mobile
and what-have-you clients)
SOA does not come into this. You have a single service.

How do I check for a Rails session in node-http-proxy?

We have a Rails app with a view that gets populated with data from a third-party API. Currently, this view uses a swf streamer to open a socket to the endpoints.
Recently, the API's provider has asked us to switch to long polling ajax calls, and to pipe requests through a proxy in our server.
We're considering using node-http-proxy, to take advantage of node's speed and concurrency handling in case we get high traffic. We're new to Node.js, though.
The other option we're looking at is using the Rails app itself to forward these requests, the advantage being that we could use the existing session handling.
We'd prefer to use node-http-proxy, as it seems the most elegant solution (and an opportunity to play with Node.js, of course ;), but haven't figured out how to integrate it with our app's sessions (activerecord session store on postgres).
Is there a way to do it? Are there any other auth/security/session-checking strategies using node-http-proxy in parallel with a Rails app?
Oliver

Rails as a filtering reverse proxy

I'd like to gradually transition an app from old java to a new rails app. The data flow would look like
user -> browser -> new rails -> old java
That is, the new rails app would function as a reverse proxy to the old app, and the user would never be the wiser of the original app.
As more functionality is migrated to the rails app, the java app would become used less and less.
I'm familiar with the Net::HTTP classes for requesting resources from the other app, but most examples are overly simplified, and don't facilitate the transition. A full featured gem would be able to
handle common HTTP verbs
pass and retain cookies
rewrite HTML from the old app (for instance, the old app will have
href="/something/foo.html", and the new app would have
"/newpath/bar.html")
have configurable session awareness (associate a sessionID on the
java app with the rails session, such that if you delete the rails session,
it could callback to the java app with a logout)
Performance is not a big concern.
Any pointers to such a gem? It would probably be classified as some sort of reverse proxy, man -in-the-middle, filter, etc
I would suggest not doing this in Rails itself, but rather doing it in directly in your webserver (e.g. Apache)
I have been working on a large project to migrate a Java website to Ruby, and have been using Apache mod_rewrite and mod_proxy for this purpose.
So the flow was
user -> browser -> apache -> passenger or Tomcat
Using modules within Apache itself meant that we did not need to use any of the Rails stack (and associated CPU/memory/threads). It also allowed us to meet one of your requirements to ensure that "the user would never be the wiser of the original app"
Session management is the only tricky part to this; I introduced a cookie that the Java and Rails app could both read, and used the presence of the cookie to tell Ruby or Java if the user was logged in. This way, Ruby and Java did not need to try to manage each other's sessions.
Hope some of that proves helpful?

Resources