-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recommended approach to share session information between applications on subdomains #2414
Comments
Hello @Fronix ! So the main challenge is, like you said: "it's going to be a hassle getting the tokens to be refreshed correctly since it has to be signed by the author (eg. auth.mydomain.com)". I hope i was able to explain all properly (english is not my main language!). Thanks! |
@raphaelpc I see what you are trying to accomplish here and yes it should be possible. You might be able to accomplish this by fetching |
Good news, i spent the last day trying and researching and trying and researching and was able to resolve the biggest of my problems! 🗡️ The default way that "fetch" works is to only send the cookies (credentials) with requests to same-origin URLs:
Ref: https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch So, to force "fetch" to send the cookies, it has to be made like that:
But, doing like that, i got a series of all new errors related to CORS (WildcardOriginNotAllowed). After a lot of digging, i found out that:
So i changed the next.config.js of my AUTH application to be like that:
This way, i can now do a request to my AUTH application from the other applications on my domain to obtain the session information. I will still lose LOTS of functionalities that i would have if i had only one application with NextAuth in it, like refreshing the exp of the JWT when changing tabs, but i believe this is the best possible outcome in a situation like mine, where i can deal with legacy applications. So, since i'm now able to get the session, the only question remaining is: i still don't know if that is the recommended approach to share the session information between my applications. :) Thanks in advance! |
@raphaelpc Great that you solved it! About the refreshing part, you can go with my suggestion of using a hidden iframe to periodically load your It would require you to add this to all your application, but a simple package that you can load via JavaScript should do it. Something simple as this <iframe height="0" width="0" src="https://auth.domain.com/url/to/something/that/refreshes/token"></iframe> |
@Fronix that is a great suggestion! For now i will leave this open in hope that someone involved with the maintainance of NextAuth, like @balazsorban44, can give my summary a look to identify if the approach is correct. I also think this could be included somewhere in the docs (or i may create a Medium post with this solution, if correct? ) Thanks! |
Will have a look when I have the time. 😊 hopefully some time the next week or after that. this issue is complicated to wrap my head around, but I know it's a sought-after feature. Thanks for the research and findings! |
Is it possible to support single sign on using next-auth with custom domains (rather than just subdomains as shown here)? |
Safari has discontinued sending HttpOnly cookies cross-domain, and I assume most browsers will follow suit soon enough. So getting this to work across domains seems unlikely, but let me know if I'm completely wrong 😅 |
Interesting, though Auth0 and other auth providers are still able to offer custom domain SSO so it must be possible somehow. Similar to how when you sign in on Gmail, you can navigate you Youtube and still be signed in |
The iFrame & PostMessage API approach sounds like a great way to get cross domain SSO working by sharing the session cookie stored on the canonical URL (auth.domain.com) between domains. I'm trying to figure this out currently but am hitting several blockers. Did you ever manage to get this working with next-auth? |
@ericvanular I also don't think NextAuth can be used to authenticate across sites on different domains. The biggest thing that i think you have to take a look is that the way NextAuth works is different from the way that Auth0 (or, for example, Keycloak) works. NextAuth is not a single signon service like those two. It just creates a cookie with the auth information, and has several methods implemented that makes that secure. To make it work across subdomains, all i had to do was play with the configurations of that cookie and of the fetchs (like using { credentials: 'include' } on my fetchs) ans CORS. But it's not secure to have cookies from a domain be sent to other domains, and i believe that most browsers currently block that. If you have to share authentication between applications on different domains, i think you will have to look for something like "https://www.keycloak.org/". |
@raphaelpc thank you for the suggestion of Keycloak. I understand that SSO across different domains presents a number of additional challenges. I did find this SO answer: https://stackoverflow.com/questions/64091604/authentication-across-across-multiple-domains-cors-with-nextauth in which @iaincollins mentions that it is a planned feature for next-auth. I'm curious if this is still on the roadmap and if there is anything we can do to help progress. Running and maintaining a Keycloak instance presents its own challenges and it would incredible if we could leverage next-auth for this functionality instead |
If it is, that was planned by Iain, who hasn't shown interest in contributing recently. I don't plan to add it in the NEAR future, but maybe some time later on. It is mainly because I lack the required knowledge at the moment. If anyone with security background want to take a stab at it and either open a PR or su. up what would be required from next-auth, please do! |
I added required changes to the backend to enable cookies sharing across subdomains and tested it with few projects. https://github.com/eugenehp/next-auth/tree/eugenehp/subdomains Comments about cookies above are on the right track too. Here's my other comment about
|
My system using the NextAuth login implementation goes into production next week or the other, wish me luck kkk |
Nice work, @raphaelpc! Eagerly waiting for your results. I would like to read up and if we can, I would like to make the configuration for this easier. |
Hi there! It looks like this issue hasn't had any activity for a while. It will be closed if no further activity occurs. If you think your issue is still relevant, feel free to comment on it to keep it open. (Read more at #912) Thanks! |
Hi there! It looks like this issue hasn't had any activity for a while. To keep things tidy, I am going to close this issue for now. If you think your issue is still relevant, just leave a comment and I will reopen it. (Read more at #912) Thanks! |
Hey @raphaelpc - how did your deploy go with your implementation? Did you get closer to getting this use case working? |
A minimal reproduction example would be nice :) |
I'm looking to get this setup working as well. I've got a couple of Next sites under a single domain and would like them to share a single NextAuth server. I've got everything else working just fine (cookie shared across subdomain, JWTs packed and unpacked successfully on all the servers) except for the case where refocus initiates a The cookie is not being sent when the request is not initiated by the domain where the cookie was issued. This is because fetchData is missing A lightweight fix to this would be to accept default fetch options in SessionProviderProps. How does this sound @balazsorban44 ? I'm happy to pop in a PR. EDIT: Raised #3735 |
@raphaelpc did you ever go live with this solution? |
I am trying to implement something similar, and after struggling with quite a few discussion threads and my own lack of knowledge around a lot of these pieces, I threw together a minimal example using create-next-app templates and some bare bones next-auth configuration plus the relevant bits of this discussion thread. This repo contains a lot of copy and paste from this thread, and the non-development portions (i.e. anything running outside of localhost) I haven't tested directly. But it should hopefully serve as a basic idea of how this discussion went. I have also not implemented anything regarding the iframe refresh strategy discussed above. Any comments are welcome, hopefully it is helpful to someone. https://github.com/jaydavid/next-auth-subdomain Edit - the only thing that I can think of that I added was a bit in the auth application that deals with redirecting. I was having some trouble with it defaulting to the base URL for the auth app and so I added a small callback to handle redirects using the same host name. There might be a better way to do this, or it may have even been discussed above and I am mistaken - but I wanted to call it out in case it's a piece that anyone needs to focus on. Its current implementation as of writing this comment: callbacks: {
redirect: async ({ url, baseUrl }: { url: string; baseUrl: string }) => {
if (new URL(url).hostname === hostName) return Promise.resolve(url);
return Promise.resolve(baseUrl);
},
}, |
Question 💬
Hello! First of all, thanks for all the great work on this amazing library!
I'm trying to implement a solution in which i have the same authentication on subdomains as well as on main domain.
What is the recommended approach to share session information between all applications?
This is a continuation of a discussion that started on some previous issues, like #405, #794, #1668.
All those issues are now closed without a full example or definitive answer, so i decided to make a summary of what was previously discussed, in hope that i can get some help on deciding what is the best approach to do that integration on all domains and subdomains of my application and help document that approach for others in the same need.
How to reproduce ☕️
The application i'm working on is, actually, an ecosystem of applications, and not all of them are made with Next.js (or even with React). Many are legacy applications written in JSP.
The main one isn't an Next.js app and will live in "www.my-domain.com".
It will have sub-domains, as in "app1.my-domain.com", "app2.my-domain.com", etc.
As explained in the FAQ:
So, since the main application isn't a React / Next.js app, I will have to implement an auth application so i can use NextAuth: "auth.my-domain.com". Notice that it's the ONLY application that includes NextAuth - from my understanding, it makes no sence to add NextAuth to all my other Next.js applications.
I created a diagram to help illustrate the ecosystem:
To set a custom cookie domain policy for the Session Token cookie, i did in my [...nextauth] API route what was originally posted by @Xodarap in #405 (comment):
Doing like that, i was successfully able to access the cookie "__Secure-next-auth.session-token", created by "auth.my-domain.com" and set in the domain ".my-domain.com", in all my other applications.
@iaincollins said in #405 (comment) that he was evaluating ways to make that configuration easier, but the issue #405 was closed because of inactivity.
As @iaincollins explained in #417 (comment):
So in regards to the protection needed to secure my backend all is done: the backend will receive the cookies together with the requests made by the frontend and decode and verify the identity of the user.
What i still don't know is what is the best approach to sharing the session information between all the frontend applications. Should i just read the information in the cookie in each of my applications? Because, doing like that, the cookie lifespam won't be increased, like happens when i access the "session" endpoint or the "useSession" / "getSession" client. For example:
next-auth/src/server/routes/session.js
Lines 58 to 62 in 75ca097
@iaincollins posted in #796 (comment) a quite great explanation of the challanges of defining the maxAge of the JWT. I quote:
So i think it would be of great loss if we don't access the session via the "session" endpoint and, as a result, lose on that great functionality provided by NextAuth.
The problem: As @subhendukundu commented in #794 (comment), i'm also having problens trying to use the endpoints provided by NextAuth on my "auth.my-domain.com" (like "https://auth.my-domain.com/api/auth/session") application.
First, i was getting CORS related errors when i tried to consume the endpoints. About those, i get that may be related to the way Next.js protects it's API routes, but i think it is usefull to document the solution here, since it will be a mandatory step for the solution to work. I followed the guide provided in the Vercel documentation and in the Next.js documentation - in the "next.config.js" file, i created a "headers" function:
(edit: the code i previously posted to configure CORS was wrong (i was checking the host of the request, and the correct way to do that is checking the "Origin" header).
With that configuration, my applications on my subdomains can access the auth endpoints from my "https://auth.my-domain.com", and it still keeps protected from access made from other domains.
I'm using "fetch" to get the data from the "https://auth.my-domain.com/api/auth/session" endpoint. Something like that:
If i do that fetch inside my "auth.my-domain.com" application, it works as expected, bringing the session information.
The problem is that, if i try to do that same fetch from my "app2.my-domain.com", for example, i don't receive the session information, only an empty object ({}). Why is that happening? Did i do something wrong?
Also, despite all the references i provided, i still don't know if that is the recommended approach to share the session information between my applications.
Thanks in advance!
Documentation feedback
Contributing 🙌🏽
Yes, I am willing to help answer this question in a PR
The text was updated successfully, but these errors were encountered: