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

**URL:** <https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624>\
**Category:** Questions & Answers\
**Tags:** question\
**Created:** [January 26, 2022, 6:32am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624 "2022-01-26T06:32:14Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 26, 2022, 6:32am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/1 "2022-01-26T06:32:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [January 26, 2022, 7:59am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/2 "2022-01-26T07:59:22Z")

</div>

Do you have a shared database?

---

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 26, 2022, 7:52pm UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/3 "2022-01-26T19:52:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 27, 2022, 7:36pm UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/4 "2022-01-27T19:36:12Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [January 27, 2022, 10:45pm UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/5 "2022-01-27T22:45:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 27, 2022, 11:33pm UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/6 "2022-01-27T23:33:04Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 27, 2022, 11:34pm UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/7 "2022-01-27T23:34:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [January 28, 2022, 5:43am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/8 "2022-01-28T05:43:57Z")

</div>

> 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]:

```scheme
(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](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](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](https://github.com/soegaard/racket-stories/blob/master/app-racket-stories/control.rkt#L128)

---

<div class="post-metadata">

**Author:** ![Byron](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Byron](https://racket.discourse.group/u/Byron)\
**Post date:** [January 28, 2022, 5:45am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/9 "2022-01-28T05:45:19Z")

</div>

Thank you. I'll check it out.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [January 28, 2022, 9:55am UTC](https://racket.discourse.group/t/single-sign-on-across-racket-and-non-racket-based-servers/624/10 "2022-01-28T09:55:14Z")

</div>

A lot more about session cookies here:

> **[Session Management - OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)**
>
> Website with the collection of all the cheat sheets of the project.
