# Use Ghost members auth to log-in to custom app via cookies

**URL:** <https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608>\
**Category:** Memberships & subscriptions\
**Created:** [March 11, 2020, 5:35pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608 "2020-03-11T17:35:54Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![rymdluo](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/rymdluo/32/6797_2.png) [@rymdluo](https://forum.ghost.org/u/rymdluo)\
**Post date:** [March 11, 2020, 5:35pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/1 "2020-03-11T17:35:54Z")

</div>

I am creating a small app that to compliment the content on Ghost for my members and I would like a way for the app to only qualify members who are logged in via the Ghost site. To clarify, I would like to solely rely on Ghost’s authentication system for my app.

I did some scouting, it looks like the following cookies are stored for members.  
`__cfduid, ghost-members-ssr, ghost-members-ssr.sig, ugid`

Additionally, after exploring the database a bit I found the following in the settings table:  
`members_public_key, members_private_key, members_email_auth_secret`

I am also aware of possible relevant tables such as `session` and `members`. Could someone explain to me how they all tie together?

### Here is my assumption of how it might work:

`ghost-members-ssr.sig` is the public key that I would use the `members_private_key` to decrypt via RSA, revealing the session info that I can use to check if the user is qualified i.e. ghost-members-ssr matches user email from backend and cookie has not expired. That said, there are some obvious gaps in my knowledge and I am unsure what the other cookie variables and `members_email_auth_secret` represent so I thought it would be best to check first before starting. Also, the decryption method is using RSA?

---

<div class="post-metadata">

**Author:** ![marcus](https://avatars.discourse-cdn.com/v4/letter/m/85e7bf/32.png) [@marcus](https://forum.ghost.org/u/marcus)\
**Post date:** [March 12, 2020, 1:51am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/3 "2020-03-12T01:51:38Z")

</div>

I’m also interested in learning about this.

---

<div class="post-metadata">

**Author:** ![egg](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/egg/32/1691_2.png) [@egg](https://forum.ghost.org/u/egg)\
**Post date:** [March 12, 2020, 9:55am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/4 "2020-03-12T09:55:51Z")

</div>

Hey!

This is definitely doable but it’s gonna be a hack either way as these are not publicly documented or stable methods.

You can either get a JWT for a member and use that to authenticate into your application, but this won’t handle logout when the member logs out of Ghost. Or you can use the cookies like you say, but this will be a little more involved and require your app to be running on the same domain so that the cookies can be shared.

## External auth with JWT

You can make a GET request to /members/ssr in your theme which will give you a JWT and then send that to your application to validate (with `members_public_key` in the settings) and initiate a session. An example of a call to this endpoint is here: [https://github.com/TryGhost/Ghost/blob/master/core/server/public/members.js#L75-L81](https://github.com/TryGhost/Ghost/blob/master/core/server/public/members.js#L75-L81)

## External auth with cookies

For this to work your app will have to be on the same domain as your Ghost site so they can share cookies.

You can take a look at the members-ssr package here: [Members/packages/members-ssr at main · TryGhost/Members · GitHub](https://github.com/TryGhost/Members/tree/master/packages/members-ssr) and use the `getMemberDataFromSession` method. In order to use this you’ll have to pass in the required settings which you can get from the Ghost settings table. You’ll also have to pass in a `getMembersApi` function which returns a proxy to a members API object - the only method you’ll need is this one: [Members/packages/members-ssr/index.js at main · TryGhost/Members · GitHub](https://github.com/TryGhost/Members/blob/master/packages/members-ssr/index.js#L167)

To implement this method you’ll need to use either the admin API or read from the db.

Hope this gives you a good start 😌

---

<div class="post-metadata">

**Author:** ![marcus](https://avatars.discourse-cdn.com/v4/letter/m/85e7bf/32.png) [@marcus](https://forum.ghost.org/u/marcus)\
**Post date:** [March 12, 2020, 11:21am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/5 "2020-03-12T11:21:25Z")

</div>

Thanks @egg, this answers so many of the questions I’ve had over the past week. We wanted to use Ghost’s authentication in order to benefit from its members system. Basically, have Ghost handle memberships for our app (that is on the same domain).

This kind of membership integration would make Ghost attractive to SaaS start-ups. Membership/subscriber and billing/payments available for their own service, and included in their blogging platform. A double win.

Or have I misunderstood how Ghost members works?

---

<div class="post-metadata">

**Author:** ![rymdluo](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/rymdluo/32/6797_2.png) [@rymdluo](https://forum.ghost.org/u/rymdluo)\
**Post date:** [March 14, 2020, 6:22am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/6 "2020-03-14T06:22:38Z")

</div>

Those were very helpful indeed! I wanted to say I’ve implemented it but alas I can only say I’m nearly there (left with step 7 below)

1. Custom JavaScript in theme to get a JWT via /members/ssr
2. Push JWT to my app, which validates it using `members_public_key` and returns the app cookie.
3. Cookie stores the email of the member, and has the same httpOnly, secure and sameSite settings.
4. App is located as a subdir via nginx proxy.
5. When user accesses the app, nginx checks if ghost generated cookie `ghost-members-ssr’ which stores the members email is the same as the apps generated cookie.
6. On sign out, a custom JavaScript sends the members email to the app to remove the app cookie.
7. If ghost cookie expires, app won’t authenticate since it requires both ghost and app cookies.

With this setup, I’ve adopted a hybrid approach to ensure a smooth auth experience across ghost and the app while implicitly benefiting from security features set by Ghost.

Personally I hope that members account will gain the ability to add names or handles. After tinkering with this possibility, the potential to extend Ghost to create simple, integrated communities instead of relying on third party services (Disqus) or fully featured platforms (Discourse) is closer to reality than I thought!

---

<div class="post-metadata">

**Author:** ![disaza](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/disaza/32/12768_2.png) [@disaza](https://forum.ghost.org/u/disaza)\
**Post date:** [April 18, 2021, 5:31am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/7 "2021-04-18T05:31:12Z")

</div>

Thanks for the tips, Fabien!

I was able to get a JWT via API request, like you mentioned.

However, I haven’t been able to get the public key with which to validate the JWT. From searching on Github, I can see that `members_public_key` exists - but I’m struggling to see how I can retrieve it if I don’t have direct access to the database.

# My goal

Ultimately, my goal is is to build a comments tool that leverages Ghost’s memberships. When a new customer signs up, I need an easy way to get the public key with which to validate JWTs from that user’s Ghost blog.

(For example, it would be great if the user could copy/paste the public key it into my site from a settings page in - say - their admin dashboard, or perhaps I could make an API request to their blog on a particular endpoint to fetch it.)

I’ve been poking around my own blog (which is hosted on Ghost Pro), but I haven’t found the public key anywhere.

Any tips on where to find it?

Thanks,  
Dan

* * *

P.S. I opened [this other forum thread](https://forum.ghost.org/t/where-can-i-find-members-public-key-to-validate-a-jwt/21998) with this same question.

---

<div class="post-metadata">

**Author:** ![rob](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/rob/32/5633_2.png) [@rob](https://forum.ghost.org/u/rob)\
**Post date:** [September 27, 2022, 4:32pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/8 "2022-09-27T16:32:20Z")

</div>

> [@egg](#):
>
> /members/ssr

Sorry to revive this old thread, but has `/members/ssr` been moved?

I’ve just tried loading it, both directly in Chrome and via JavaScript in the site footer whilst logged in, and it 404s.

I’m looking to get a JWT for logged-in members to send to my remote API, to authenticate them as paying members before returning premium data.

I can see the public key at `/members/.well-known/jwks.json` still, but not the actual JWT payload at `/members/ssr` with user data in it.

Thanks,

Rob

---

<div class="post-metadata">

**Author:** ![frei](https://avatars.discourse-cdn.com/v4/letter/f/50afbb/32.png) [@frei](https://forum.ghost.org/u/frei)\
**Post date:** [September 27, 2022, 10:38pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/9 "2022-09-27T22:38:18Z")

</div>

Same experience that I am having.

—We have a custom API running along with Ghost and are [successfully authenticating members](https://forum.ghost.org/t/get-jwt-for-signed-in-member/32955).

We want to learn: How to authenticate against the admin cookie credentials?

---

<div class="post-metadata">

**Author:** ![rob](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/rob/32/5633_2.png) [@rob](https://forum.ghost.org/u/rob)\
**Post date:** [September 28, 2022, 8:47am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/10 "2022-09-28T08:47:58Z")

</div>

The best I can see so far, is to fetch `/members/api/member/` and then check the `uuid` on the backend via the `/admin/members/` API. But that would only confirm that the UUID has a paid membership, not that the current logged-in user owns that uuid, making it exploitable. A JWT payload would be perfect for this.

---

<div class="post-metadata">

**Author:** ![egg](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/egg/32/1691_2.png) [@egg](https://forum.ghost.org/u/egg)\
**Post date:** [September 29, 2022, 4:10pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/11 "2022-09-29T16:10:44Z")

</div>

`/members/ssr` has been replaced in favour of `/members/api/session`

---

<div class="post-metadata">

**Author:** ![Jacob74](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/jacob74/32/19666_2.png) [@Jacob74](https://forum.ghost.org/u/Jacob74)\
**Post date:** [October 1, 2022, 6:41am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/12 "2022-10-01T06:41:19Z")

</div>

I’m looking to get a JWT for logged-in members to send to my remote API, to authenticate them as paying members before returning premium data.

---

<div class="post-metadata">

**Author:** ![benclmnt](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/benclmnt/32/26825_2.png) [@benclmnt](https://forum.ghost.org/u/benclmnt)\
**Post date:** [October 15, 2023, 4:05am UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/13 "2023-10-15T04:05:50Z")

</div>

Wrote up both JWT and Cookie solution here: [Use Ghost authentication to login to custom app](https://blog.benclmnt.com/blog/ghost-custom-app-auth)

---

<div class="post-metadata">

**Author:** ![Cathy\_Sarisky](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/cathy_sarisky/32/25750_2.png) [@Cathy\_Sarisky](https://forum.ghost.org/u/Cathy_Sarisky)\
**Post date:** [October 18, 2023, 4:32pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/14 "2023-10-18T16:32:08Z")

</div>

Interesting summary, but you may want to fix the factual error in your first paragraph. Ghost does not do email/password authentication for members.

I see your blog isn’t hosted on Ghost - would you mind linking your site where you do use Ghost? I’m always interested to see where new users who are linking blog posts about Ghost are actually using it!

---

<div class="post-metadata">

**Author:** ![einar](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/einar/32/30105_2.png) [@einar](https://forum.ghost.org/u/einar)\
**Post date:** [May 29, 2024, 4:22pm UTC](https://forum.ghost.org/t/use-ghost-members-auth-to-log-in-to-custom-app-via-cookies/12608/15 "2024-05-29T16:22:31Z")

</div>

Is there currently a working way to reuse the ghost membership login for other custom apps (on other domains?). Does @benclmnt workaround work still, and has it been battle tested?

I really believe this would unlock a lot of power with memberships for advanced users, if there was an officially supported solution…
