2 Rails Applications sharing same login system


#1

Hi i have 2 seperate rails applications. They both share the same login
system.

If someone is logged into application 1 then they should be able to
start using application 2 without logging in again. I am unsure how to
achieve this.

I’ve a feeling i can somehow do it by telling both the apps to share a
cookie, but i’m not sure.

Does anyone know how to do this or has anyone done it?

Any help appreciated.

Thanks

Chris


#2

If both apps are on the same box / have access to the same database
(e.g.
distributed servers), then this is as easy as setting a flag in the
database
and making sure both apps look for this flag and auto-login as needed.

Otherwise, the first thing that comes to mind is to have a special key
generated for the user that’s send between apps to warn said app of an
incoming already-logged-in user. This will of course be more complicated
in
terms of determining a proper “identity token” generation algorithm and
keeping the transaction secure.

You can’t share sessions or cookies across sites.

Jason


#3

Gave it a little more thought and yeah, there’s a special step you’ll
need

Assumptions:

  • Both web apps are on the same box or have access to the same database
    server
  • App1 and App2 are treated as seperate entities (not using the same
    database between them)
  • App1 has its database, App2 has its database, and both can access a
    third
    database

the third database will hold login/user information:

table User:
id
name

logged_in boolean
logged_in_on datetime (or timestamp, depending on database)

App1 and App2, when a user visits the site will query this table when do
the
user authentication/authorization. If the user isn’t logged in, or the
logged_in_on field is too old (for you to decide), then log the user in
and
update the fields. Of course, I’m also assuming that logging out of one
means logging out of both.

Hope that helps describe what I’m thinking.

Jason


#4

Yeah they are on the same box.

If both apps are on the same box / have access to the same database
(e.g.
distributed servers), then this is as easy as setting a flag in the
database
and making sure both apps look for this flag and auto-login as needed.

Exactly what do you mean? What would the flag contain and how would it
work? Would it have to contain the IP address for the user? DOesn’t
it also rely on them manually logging out of the system? or would you
use timeouts?.

Thanks for the reply


#5

I have a similar problem but my second app is deployed as a subdomain to
the
first app. However second app is a different app al together with
different
database and may or may not be deployed on the same box. It’s just that
the
second app is services.eii.com while the first app is just app.com

-=-


#6

App1 and App2, when a user visits the site will query this table when do
the
user authentication/authorization. If the user isn’t logged in, or the
logged_in_on field is too old (for you to decide), then log the user in
and
update the fields. Of course, I’m also assuming that logging out of one
means logging out of both.
Hope that helps describe what I’m thinking.
Jason

So if the user visits site 2 after logging into site 1, how can site 2
do any kind of user authentication? how will it know which user to look
for? So lets say there are ten users logged into site 1, how will site 2
know which user to look for? Maybe you store the IP address of the
logged in machine, so then app 2 can check if any users with the current
IP are logged in. But using the IP address isn’t a reliable method.

THanks

Chris


#7

Jason,

How will you know that the user is already logged in? You will still
need a way to identify him, so the user must identify himself somehow
in the other app (only username will do then, but still it needs to be
provided (unless the link also sends the username from the other
app)).


#8

Open ID would be of tremendous help but not everyone is using open id.

This is how I am going to solve the problem for app1 and app2.

app1 uses db1
app2 uses db2
and there is also db3. This database db3 will have only one table with
four
columns: login_id ,key , created_at and updated_at

Let’s say that user1 logs into app1. Once the user is successfully
authenticated, a record will be inserted in the table in db3. Now
anytime
the user switches from app1 to app2 then pass the key along with it.
App2
receives the key ‘1234567890’. App2 will access db3 and will try to see
if
this key exists, if yes then get the userid. Now this userid is logged
into
app2.

Anytime user is switching the from app1 to app2 then update the column
updated_at. Run a cron job that will delete this record when updated_at
is
more than one hour old.

Also if the user logs out clicking logout link then delete the record
from
db3.


#9

Sorry, I just realize that I had another seemingly untrue assumption:
users
get to site1 from site2 and vice-versa. Without this assumption, I can
see
how this is a very difficult problem. So, then, is this really
necessary? If
the two sites are to be completely separate from each other, why do you
want
to keep the login information the same?

You can’t check IP address because those change.
Anything else you check will require the user entering in something, so
it
might as well just be an unlinked login system (even OpenID, unless
there’s
some desktop utility to auto-fill such fields, will require the user to
enter in the login).
And if you require the user to enter in just the login name, there is a
very
large security hole by not also requiring password.

So if the sites are related, and one clicks on links on site1 that take
you
to site2, then my solution will work, passing along a key through GET or
POST. Otherwise, if the user manually visits each site, they’ll need to
enter in full credentials.

Jason


#10

Raj S. wrote:

I have a similar problem but my second app is deployed as a subdomain to
the
first app. However second app is a different app al together with
different
database and may or may not be deployed on the same box. It’s just that
the
second app is services.eii.com while the first app is just app.com

-=-

Would OpenID be of some use here? Not as a total solution, but kind of
moving the whole login process to a service, so the “which box/database”
question is less important. I’m really asking, not suggesting – it
looks like it would help, but I’m not sure.

Ron


#11

You can’t share cookies between domains, but you can use page
redirection coupled with an authentication table in the backend to
sync cookies between domains. Here’s brief writeup on how 43 Things/
Places/People share auth:

http://dev.robotcoop.com/Technology/xs_auth.html

In that case we did have the “luxury” of sharing the same database, so
the apps could access the same auth table trivially.


#12

Or you could do it with REST… which is more the rage in the rails
world these days.

Scaffold resource yourself a Login model in app 2… you’d probably want
user info and an expiration time (probably keep it less than a minute).
Then app 1 POSTs the xml to app 2 and gets back a response with the url
of the created login in the Location header.

App 1 can then redirect the user to that url and you make the
logins_controller check the expiration time and then log the user in on
the second system.

For security reasons, you may want to use a uid instead of the id in the
redirect url. Also, you’ll want to be careful that only app 1 can make
that REST call to app 2.

b


#13

You could develop a simple web service or xml-rpc routine that hits up
against one of the databases. The web service could read or set the
boolean discussed above. Check out the XML-RPC screencast on
http://www.rubyology.com

Chris Matthieu
http://www.Rubyology.com