ory / kratos

Next-gen identity server replacing your Auth0, Okta, Firebase with hardened security and PassKeys, SMS, OIDC, Social Sign In, MFA, FIDO, TOTP and OTP, WebAuthn, passwordless and much more. Golang, headless, API-first. Available as a worry-free SaaS with the fairest pricing on the market!
https://www.ory.sh/kratos/?utm_source=github&utm_medium=banner&utm_campaign=kratos
Apache License 2.0
11.04k stars 950 forks source link

NextAuth Support #2179

Open Immortalin opened 2 years ago

Immortalin commented 2 years ago

Preflight checklist

Describe your problem

Ory Kratos does not support https://next-auth.js.org/, Kratos currently requires a lot of custom code to integrate. NextAuth supports FusionAuth, Keycloak, and Auth0 as providers, but not Ory Kratos.

Describe your ideal solution

Ory should create a first party NextAuth provider and send a pull request to the NextAuth repo.

Workarounds or alternatives

N/A

Version

latest

Additional Context

No response

xlanor commented 2 years ago

I'd be open to take a look at this if @aeneasr is opento the idea - I'm just getting back into contributing back to OSS, been busy with life.

Correct me if I'm wrong though. Isn't this more on next-auth's repo than kratos?

aeneasr commented 2 years ago

Hey there! Great idea and we’d love contribs in this area! We also have guides for NextJS already (with video) that will be quite helpful I believe: https://www.ory.sh/login-spa-react-nextjs-authentication-example-api-open-source/

vinckr commented 2 years ago

Can we use the credentials provider @Immortalin ? https://next-auth.js.org/configuration/providers/credentials

In any case, if someone wants to start working on this, I will be very happy to support. Please feel free to ping me at any point.

ShahriarKh commented 2 years ago

Any updates on this?

vinckr commented 2 years ago

@ShahriarKh I suppose not. Always open for contributions & also supporting them along the way!

atreya2011 commented 2 years ago

The way I integrated with NextAuth is by creating a Custom OAuth Provider using Hydra and then integrating Hydra and Kratos. Then all we have to do is add the custom provider to the NextAuth config

https://github.com/atreya2011/next-auth-kratos-hydra-test/blob/main/pages/api/auth/%5B...nextauth%5D.ts

However, integrating Hydra and Kratos together is a bit of a difficult task by itself 😅

Using the credentials provider to integrate only Kratos with NextAuth seems like a good idea, as @vinckr mentioned.

Will code contributions to this issue go to this repo or the example NextJS repo?

vinckr commented 2 years ago

Will code contributions to this issue go to this repo or the example NextJS repo?

Good question. I think it would be best as guide / example integration in the docs! https://github.com/ory/docs/

"Integrations/NextAuth" would make sense IMO, as we also have integration guides for other 3rd party services in the pipeline.

Let me know if you would be interested in contributing and if I can help with this.

amorey commented 2 years ago

I'm also trying to integrate kratos with next-auth and here are some of the approaches I'm considering:

  1. Next-Auth CredentialsProvider with Kratos browser flow (h/t @vinckr)

    If you want to use the browser flow to login/register with kratos then I think the most straightforward way to initialize the next-auth session is to call signIn('credentials', {redirect: false}) from the client after obtaining a kratos session cookie. Then server-side you can call /sessions/whoami from the CredentialsProvider's authorize() method to obtain the user's identity and return it to next-auth (using the kratos cookie available to the request object). Overall, the drawback of using this method is that you have to maintain kratos and next-auth sessions simultaneously and deal with edge cases where one is expired but the other isn't.

  2. Next-Auth CredentialsProvider with Kratos API flow

    To make it easier to manage the kratos and next-auth sessions simultaneously you can use the kratos API flow instead of the browser flow. This will allow you to perform kratos operations (e.g. logout) on behalf of the user server-side more easily (using the session token which can be saved in next-auth's encrypted JWT). Another benefit is that once the next-auth session expires or is deleted, the kratos session token will be erased automatically as well. The big drawback of using the API flow is that you have to implement security features yourself though you can at least piggy back on next-auth's CSRF protection by proxying login/registration calls to kratos through next-auth signIn() method.

  3. Next-Auth Custom OAuth Provider with Kratos + Hydra (h/t @atreya2011)

    Next-Auth is designed to work with OAuth so this seems like the most robust way to integrate it with kratos but this will add another dependency which might make development more difficult. I haven't set up hydra before so maybe there's a way to set things up in a developer-friendly way though (e.g. run on docker and proxy through next?).

  4. New next.js client-side library for kratos with similar behavior to next-auth

    Personally, I just want to use next-auth's client-side features with kratos as a back-end so maybe the best thing to do is to create a client-side library for kratos modeled on next-auth. The drawback here is the time it will take to write/test/maintain a new library.

What do you think? Do you have other suggestions for how to integrate kratos and next-auth?

atreya2011 commented 2 years ago

@vinckr Sorry for not being able to reply sooner regarding this 🙇🏼 I have the following sample repo demonstrating Kratos+Hydra integration that works with Next-Auth. https://github.com/atreya2011/next-auth-kratos-hydra-test/blob/main/pages/api/auth/%5B...nextauth%5D.ts However, I am not sure that this can serve as a starting point to make a good guide...

@amorey Thank you for the detailed write-up on all the possible approaches!

I did try approaches 1 and 2 and it was just messy, to be honest. As mentioned above, Next-Auth is designed to work well with OAuth; hence 1 and 2 seem like a roundabout way of using Next-Auth to achieve something which can be quickly done by just using Kratos! As for no. 4, I think there is already a client-side library for Kratos that works well with Next.js.

From my understanding, Kratos by design is not an OIDC-compliant identity provider. We can however implement one by combining Kratos with Hydra. This would make it easy to integrate such an implementation with a library such as Next-Auth which is designed to work well with OAuth 2/OIDC compliant Identity Provider.

amorey commented 2 years ago

@atreya2011 Thanks for your reply and for sharing your code! Here are some questions:

atreya2011 commented 2 years ago

@amorey

image

amorey commented 2 years ago

@atreya2011 Thanks! This is very helpful.

aeneasr commented 2 years ago

Wow great job @atreya2011 !! :)

I also wanted to inform you that we are actively working on a native integration between hydra and kratos and expect it to land relatively soon as the core things are working already but still need more testing as well as support for various flows (login, registration, mfa, ...)

atreya2011 commented 2 years ago

@aeneasr

Thank you 🙇🏼 The above flow is actually a combination of the flows already provided in the official documentation of Kratos & Hydra. Awesome! Looking forward to the native integration 🙏🏼 Is there any way I can contribute to the development of the native integration?

amorey commented 2 years ago

@aeneasr That's great news! Do you have an estimate on when it will be ready to try out? I'm currently working on a hydra+kratos integration and it would be very helpful to have a native solution.

amorey commented 2 years ago

@aeneasr In case it's useful, here's a Hydra reference implementation for Next.js: https://github.com/amorey/hydra-nextjs-reference

Any updates on the hydra+kratos integration?

amorey commented 2 years ago

Also, here's the same reference implementation with TypeScript: https://github.com/amorey/hydra-nextjs-reference-ts

atreya2011 commented 2 years ago

@amorey Nice!

atreya2011 commented 2 years ago

@amorey The integration is work in progress over here 👇🏼 https://github.com/ory/kratos/pull/2549

vinckr commented 2 years ago

Also, here's the same reference implementation with TypeScript: https://github.com/amorey/hydra-nextjs-reference-ts

Woah awesome, thanks for sharing those! Would you be open to contribute them to /ory/examples? So people can find them there and the community can help out with maintenance :)

amorey commented 2 years ago

I'd be more than happy to contribute them to /ory/examples! Would you prefer to do a fork or a repo transfer?

atreya2011 commented 2 years ago

@amorey It looks you can make a PR with your example by creating a folder for it? https://github.com/ory/examples/pulls

vinckr commented 2 years ago

Exactly, you create a folder for each example - apologies for not being clear there. I also realize the CONTRIBUTING.md does not mention this at all - will fix.

amorey commented 2 years ago

Done https://github.com/ory/examples/pull/43 https://github.com/ory/examples/pull/44

mattbarnicle commented 1 year ago

@amorey have you made any progress on creating an implementation of Next-Auth + Kratos? i'm specifically interested in your point 3 in response to @atreya2011, as this is exactly what i'm trying to achieve in my setup:

"Next-Auth Custom OAuth Provider with Kratos + Hydra (h/t @atreya2011)"

amorey commented 1 year ago

Yes, I ended up implementing the Kratos consent flow with Next.js and then using the native Kratos+Hydra integration (see https://www.ory.sh/docs/kratos/reference/configuration). I think I used @atreya2011 code as a starting point but it was a while ago so I don't remember and unfortunately the code I'm using is not in a state I could easily open source. If you want to share your progress, maybe I can help.

mattbarnicle commented 1 year ago

@amorey that's great. i'm glad to see someone has done this successfully. as for myself, i don't know what i can share with you that would be useful. basically i just don't understand what i need to do. i'm looking for an example i can look at so i can follow through the code and poke around in it.

i managed to take the code from this implementation (https://github.com/ory/kratos-selfservice-ui-react-nextjs) and get it working within my code base, but i don't know what i'm supposed to do next.

for a little background, the reason i'm trying to do this is that we've got 3 different sites with different domains that we're trying to get working through the same centralized auth. and the Ory guys told us that we need to use Hydra as authorization via OIDC + Kratos as identity provider.

vinckr commented 3 months ago