Single Sign-On across Racket- and non-Racket-based servers

Any recommendations for implementing single sign-on across multiple (in my case two) Racket web servers and a Node server for a React-based UI? The user should be able to login on the main server (Racket) and select a React.js app that will run on a Node.js server. The React app will make API calls to a second Racket-based server.

Is "single sign-on" too grandiose a term for this set-up. Is there a simple way to do it?

Byron

Do you have a shared database?

1 Like

Yes, the database will be shared between the two Racket servers. There's no reason it couldn't be shared with the Node server, too.

I'm probably overthinking this. I just need to encode the user credentials in the URLs to the secondary servers.

If I understand you correctly, this would mean that if a user A sends a page link to another user B, user A accidentally gives their credentials to user B. For this reason, putting credentials into an URL is a bad idea. Slightly less bad are credentials in a post request or in a cookie, but it's even better to use a (time-limited) session cookie. If you want, you can store the current session cookie for a user in the database.

How does a second server recognize the user by a session cookie in the database?

Thank you, by the way, for patching my mental bugs.

1 Like

How does a second server recognize the user by a session cookie in the database?

The same way the first server does.

The code for Racket Stories offers a concrete example.

The model (database) records a session on successful login.
The session is represented like this [1]:

(define-schema session
  ([id             id/f       #:primary-key #:auto-increment]
   [user-id        integer/f]
   [token          string/f]
   [created-at     datetime/f]
   [expires-at     datetime/f]))

When the session is created a random token is generated.
On the user side the token is stored in a cookie.

Since they are stored at the user side, we need to check that the session cookie isn't tampered with.
This check happens here in "control.rkt" [2].

Finally dispatch which receives the request needs to check whether the request comes from a logged-in user before anything else happens [3].

[1] https://github.com/soegaard/racket-stories/blob/master/app-racket-stories/model.rkt#L655
[2] https://github.com/soegaard/racket-stories/blob/master/app-racket-stories/control.rkt#L58
[3] https://github.com/soegaard/racket-stories/blob/master/app-racket-stories/control.rkt#L128

2 Likes

Thank you. I'll check it out.

A lot more about session cookies here:

3 Likes