Auth.js Authentication for the Web
authjs.dev
authjs.dev
Seems like many people are trying to shoehorn their codebase [2] (!!) to make it work with the way the library manages sign-in flow, redirects, cookies, logout, etc. [3]
These were solved problems in the MEAN stack era with middlewares, but now that Next.js/react is the trend, people are doing everything they can to make it work - from relaxing security configs, to stashing things in the JWT just so some callback can get an additional piece of data [4].
[1] https://github.com/jaredhanson/passport
[2] https://github.com/nextauthjs/next-auth/issues/600#issuecomm...
[3] https://stackoverflow.com/questions/tagged/next-auth?sort=Mo...
[4] https://stackoverflow.com/questions/64576733/where-and-how-t...
EDIT: more links in case it helps the authors improve DX
the middleware has been available for awhile, they just added a few "advanced" features it looks like.
The problem with their middleware is that it's based on their edge runtime. Which is pretty much very basic web APIs and nothing more. Unlike Express/Koa, you do not have the full node API and cannot do things like read files from the filesystem. It's a total unnecessary clusterfuck just so Vercel can get you on their cloud services. Every single day I work with Next.js I wish I had Express and a decent router.
Maybe this can help you too: https://github.com/fastify/fastify-nextjs
The only drawback is the slow startup time of next.js, which becomes really annoying with huge next.js projects. But for smaller projects, fastify-nextjs is fine.
[1] https://stackblitz.com/edit/github-mwzv1t?file=README.md
> Seems like many people are trying to shoehorn their codebase...
This is something we're always thinking about in our product; write API first and flexibly enough so developers don't have to do cartwheels to use our product.
If you ever need to jump into authentication in Node again, give us a look!
I've been struggling to integrate Stytch SDK with next-auth even though there's a tutorial for magick.link [0] that I tried to replicate to no avail.
[0] https://dev.to/narciero/using-nextauth-js-with-magic-links-d...
Full Disclosure: I work at WunderGraph
But I think you should take a look at WunderGraph. It's vendor agnostic and allows you to choose a authentication provider that will work with your codebase.
You can use Keycloak, Auth0, Ory, etc...
https://docs.wundergraph.com/docs/features/openid-connect-ba...
> The functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
I have to admit while as a dev I sympathize with this stance, as an end-user I really hate it. I pay for a pwd manager and feel much better about using a user+pwd combo. I get that oauth is more secure in general but somehow I feel uneasy to give access (even limited) to my personal gmail or github.
Webauthn looks great though, really looking forward to that taking off
On the phone, for example with Slack, it has a button like "Open email" which I click, and then it opens the email, then I click the link which takes me back to the app, works pretty well.
That said a lot of the documentation is outdated and clearly react focused. I’ve encountered a lot of behavior that’s unexplained unless you dive deep into the code or GitHub issues. For anyone using this with SvelteKit, or just in general definitely contribute to the documentation if you can! It would help a lot!
One thing I was pleasantly surprised by was how easy it is too rollout email authentication via magic links and how relatively good it looks/behaves out of the box [2]. All you need is to add SMTP url and add the config.
It is also worth noting that it doesn't work for nextjs yet.
[1]: https://github.com/nextauthjs/next-auth/pull/6132
[2]: https://aihelperbot.com/signin
Edit: Formatting.
Use a service like AWS Cognito or Auth0 to handle auth/federated connections and hand write a simple client to adapt to your auth provider.
You can have a client-side only flow or you can use a server, in either case it's pretty trivial to implement.
It still leaves a lot of authn/authz work up to you, but it simplifies putting a "log in with Google" button on your site.
I plan on doing it this way in the product that i am working on, but to save time I use a parallel auth system that just plug and plays with react and then I do some user mapping in my backend (ugly haha but for now is good)
WebAuthN/passkeys would have to be implemented on the provider side, not the client, so highly unlikely that this is planned unless their authentication server documentation was too well hidden for me.
https://supabase.com/docs/guides/auth/overview
(and +1 to iteration speed and brevity using SvelteKit)
Super fast out of the box, but I also upgraded vite to 4 with a few overrides to get swc.
Solid Auth is still a bit immature (I ended up writing my own Auth stack around prisma, trpc and jwt), haven't tried Next Auth
I’ve heard people say “don’t write your own auth” but I’ve also spent a LOT of time hacking auth libraries to fit custom designs, custom flows, etc. And building tooling to integrate libraries with other infra: middleware, test mocks, etc.
My question is this: If you have a full time dev team maintaining an application, is it really that much slower in the long term to maintain your own auth flow?
I’ve basically given up on UI frameworks like Material UI because of this issue… if you’re building something customized, and you have full time devs to support it, the “time savings” of using a library like that is, in my opinion, a scam.
You feel like you’re getting a lot for free because the stuff that works out of the box is very visible. But the months and months of cumulative time spent dealing with the complexity that comes from customization and extension is invisible, because it’s just bugs you fix, or tasks that take a week instead of a day.
My team lost probably a dev month this quarter to react-select because of this. I’ve seen the same happen with Popper, react-table, and dozens of other supposedly helpful libraries.
I’m curious what other folks think about auth specifically though. Does auth fit into this pattern, or is it something that you really can meaningfully outsource to a library?
If you're operating within an enterprise context, Keycloak [0] is pretty massive but provides comprehensive coverage for all authN and authZ needs, and it's open source.
Back when I first started studying this topic I found that reading through a lot of NIST guidelines was helpful. I'd recommend at least browsing through SP 800-63-3 [1], SP 800-63A, SP 800-63B, SP 800-63C to get a good idea of the domain. Admittedly, this might be a lot of overkill for your application and needs.
[1] https://csrc.nist.gov/publications/detail/sp/800-63/3/final
- password reset flows
- validating & cleaning inputs
- supporting multiple SSO methods for same account
- disconnecting or switching SSO methods
- handling duplicate accounts
- handling users who lose access to their login method
- email verification
- session cache validation
- detecting risky logins
- 2FA
- the list goes on…
You can put the same logic behind loads of other enterprise software platforms. Building something like a CRM or Email management platform probably seems pretty easy, but if you look at what the SaaS products offer these days it's a mountain of features out of the box for a simple price tag. It's far, far less risky to buy than build.
Even if you don't have a huge team I'd rather handroll over using third parties.
The mental effort of thinking about some other 3rd party developers or service is not worth it. I can write an auth system in under 100 lines and be on my way to ship features. Social logins are the only annoying thing as they all use slightly different profile fields.
If you have issues with scale, scale vertically until it doesn't work anymore. By that point you'll likely have plenty of money to throw around for a registration team to worry about.
Our requirements were quite unique and so writing custom code but aligning to an OIDC style flow was a good choice for us.
In the end it was a good choice and much easier than forcing an auth framework to do something it wasn’t designed to do.
https://news.ycombinator.com/item?id=34163624#34163970 2 days ago
Fairly similar to your "build vs. free" question, including auth
Ive never understood it as "dont make an api call to some auth yourself", because really, theres no problem with that (in my mind).
Not sure this applies to Auth.js, but with hosted offerings, it's really hard to migrate off. Like how do you get the passwords into your system without forcing everyone to reset them?
Disclosure: I work for an auth provider, FusionAuth.
I've written a number of migration guides and some hosted auth providers allow you to export password hashes (usually through a support ticket/out of band process; it's sensitive data). Others do not.
Definitely worth asking. It's your data, you should be able to get it.
Here are the ones I know that allow you to get your hands on password hashes:
* Auth0 (you have to be on a paid plan)
* Firebase
* FusionAuth (my employer, you get the whole encrypted database export)
Here are the ones that don't:
* Amazon Cognito
* Azure AD B2C
Once you have the hashes, it's a matter of ensuring that you can implement the same hashing algorithm so that the same user password entered into both systems ends up creating the same hash. Not rocket science, but sometimes, depending on the intricacies of the algorithm, can require a bit of spelunking. For instance, I was working on a keycloak migration guide and while both systems use Salted PBKDF2 with SHA-256, one used a 512-bit derived key and the other used a 256-bit derived key. I had to dig in a bit to figure that out.
I speak from experience when I say that if there's something I like less than customizing MaterialUI component behavior it's working with a mangled custom-made replacement with worse semantics and functionality.
I think of it like this: is the login and registration experience going to be a differentiator for your application? If so, how? Get real clear on the business value of a unique login experience (do you need to support special protocols? unique flows? pixel perfect UX control? multiple different user stores?).
If it isn't going to be a differentiator, then use a commercial or OSS solution that meets your needs, using the usual feature, standards and stability checkboxes.
If it is going to be a differentiator, evaluate the same options, but consider building as well. Much has been written about how devs underestimate the effort to build something ( https://www.google.com/search?hl=en&q=devs%20undersetimate%2... ), but I hear you, sometimes people underestimate how much effort can go into customizing something. Include, as best as you can, the features that are going to be 'differentiated', and see if customization or build from scratch is going to be more effort. (Spikes are helpful here, but to be honest, a lot of this pain is going to depend on future requirements that, being in the future, will be hard to foresee.)
If your auth flows are simple and easy to build, they'll probably be simple to customize. And if they are complex to customize, they'll probably be complex to build and support. TANSTAAFL.
You also want to think about maintenance. This of course cuts both ways. If you own the auth code, you control it and don't have to worry about breakages out of your control ( just like having your own C compiler: https://www.joelonsoftware.com/2001/10/14/in-defense-of-not-... ), but now you are responsible when a new feature or bugfix is needed, and it falls into your existing planning process. If you outsource this functionality, you still need to do integration testing, but you hopefully won't have to redo the work. (And you have a vendor to blame/hit over the head, which may or may not be helpful.)
Another way to put it is: should you build your own data storage system? Or use an RDBMS? Neither answer is always true, but for most applications, I'd lean towards the latter. I think the same is true with auth. It's a well understood space, with a lot of good solutions; finding one and using it will probably be the best option.