Let's have an honest discussion about Lucia #1231
Replies: 35 comments 63 replies
-
I, of course personally, want keys they provide a sense of uniformity. As for passwords, I am wholeheartedly in the camp of discouraging their use. If there exists a pathway to implementing them, hand me the pieces I need to the foot gun and let me build it. Offer me resources, considerations, and disclaimers, but anything beyond that? Take care of it for me completely. Which of course, would contradict the discouragement of using them in the first place. |
Beta Was this translation helpful? Give feedback.
-
Rip the Band-Aid clean off. It only stings for a little bit. |
Beta Was this translation helpful? Give feedback.
-
I support removing keys. I'm already basically ignoring them by copying the user's Twitch ID into user attributes, just to avoid having to do a join when selecting a user by Twitch ID. I also don't use passwords but I think your reasoning is sound. |
Beta Was this translation helpful? Give feedback.
-
I feel like one of the best features of keys is being ignored here. I agree passwords should probably just die, but having unique keys for each login type allows an easy way to have users link multiple OAuth providers to the same account.
Keys also allow for easy future proofing for when there could be a mix of OAuth providers and Passkeys. |
Beta Was this translation helpful? Give feedback.
-
Speaking as a heavy user of Lucia ever since I discovered it sometime after the v1 release: I don't think Lucia, as a project, needs to go any further in terms of what it's trying to achieve.
This is on point. Auth is tedious and time consuming, and Lucia already takes a massive chunk of work out of my hands. But I think the most compelling aspect of Lucia is that the way it's structured also gives me enough flexibility to bend parts of it to meet my requirements. A few examples:
I think not covering request throttling, email verifications, and any other tasks not directly related to the session management aspect, was the correct decision so far: Lucia does one thing, and it tries to do it as well as it possibly can. I already have ownership of both the database and the API layer. If I want to use mailing, or implement request throttling, this should not fall into Lucia's umbrella of responsibilities.
This is fair, passwords are dangerous when handled incorrectly. Period. That being said though, one of the things that instantly drove me away from Auth.js is how they actively prevent you from configuring credential based authentication under some conditions. I get it, we want to make the transition to a passwordless future, and we want better tools to help us achieve that. But not every project is a greenfield one, and in the real world, we have business requirements to meet... Many times, these business requirements will tell us that a credential based authentication system is needed. So we will build/maintain them. So I agree, usage of credential based methods should be discouraged where possible (with visible warnings in the docs and some bits of developer education). But not removed.
I don't have a strong opinion about it to be completely honest. I think the feeling I have for them is, that they're fine. Yes, they are a Lucia specific concept, and yes, they do require you to adhere to a Lucia specific shape of database schema, but they never got in my way, even when working in making my authentication layer backward compatible with previous iterations (most databases will allow me to have a trigger to copy values from the I will say this though. Adding tables to a database is easier them removing them. On a personal level, for me, the removal of keys would incur in some serious refactoring on several projects where I want to keep using the latest version of Lucia. If you think this is a necessary change to realize your vision for the library, I'd say go for it. But be mindful that other authors of projects that currently use Lucia for their authentication layer in productions environments might not be too happy about it, so planning it throughly (migration guides on how to handle the database changes without losing data) is a good idea. |
Beta Was this translation helpful? Give feedback.
-
I agree with this so far (fairly new to Lucia). I appreciate Lucia's enthusiastic maintenance, docs, and thought given (e.g. architecture to sit between DB and framework, ability to use separate DBs for user data and sessions, etc). My perspective: As a user:
I'm interested in:
No opinion on keys. I'm too new to Lucia and reserving judgement. |
Beta Was this translation helpful? Give feedback.
-
I specifically moved away from Auth.js because of the limiting aspect of passwords. I understand that passwords are discouraged because due diligence still needs to be done. However, we still have requirements to have credentials logins. I don't understand the big push to get away from them when almost every new application from the private sector still requires them. I'm indifferent either way about the interactions that Lucia has with my user information. If you want to handle session management and provide oauth/password utility functions/providers, I'm game. If you go that route, I would at least lay out a checklist of things the user should provide to accomplish it correctly, not by giving code examples but by listing them out. I think for password authentication, it would be better if we had the chance to provide the users of the library additional utility functions for generating/validating TOTP to make credentials usage on the "safer" side. Removing the key table would be fine, as we can use the utility functions to validate the data from how we are storing it. Request throttling, email verification, and others should be kept out of auth as they are not directly auth-related, but maybe suggest the user implement them. Even then, you could still utilize Lucia in a passwordless capability. The user of the library would have to handle the passwordless part of it like a short-lived token at an endpoint that is emailed to them that would create a session. Medium.com does this with just an email address to create an account, and then they email you a link anytime you want to log in. This then makes a session and allows you to enter as you do. |
Beta Was this translation helpful? Give feedback.
-
Can you be specific about the care required? I only use Lucia for easier and secure way to handle sessions. That's all. For password reset and email verification, I think I can do it on my own. |
Beta Was this translation helpful? Give feedback.
-
I have followed this project on and off for awhile. Finally in the past 2 months implementing it into a production application. I have been able to make everything work well. I believe that a project should pick it one thing to do well and focus on that. So, I applaud you for really trying to find that one thing. I am too little experience to provide feedback on overall design. Though, I will say that I have recently been thinking that maybe it would be just easier to copy out the parts of Lucia that I like and integrated them directly into my project. As you mentioned, Auth is very closely tied to how a specific project works and it DB schema. Frankly I didn't really follow your above examples either... Overall, IMO I think that if you want to change the design, then you should just rip the bandaid. |
Beta Was this translation helpful? Give feedback.
-
Creator of Auth.js here.
I want to be clear. We do not make it harder to get credentials login working in Auth.js. We are pretty much on pair with the outlined goal here. Most people will be discouraged when they see that Auth.js has the artificial "limitation" that it doesn't work with a database. It literally takes ~5 lines to do it anyway though. If you don't realize it, you most likely should not implement it yourself. (We tried to make it more clear in the docs, see nextauthjs/next-auth#8482. I'll make sure this is reflected everywhere) As @pilcrowonpaper says, you need to be willing to put the care required to pull it off. I understand that this is a common option still, and that's exactly why we are keeping the option to do it, and always will! Right now we have the bare minimum. That said, passwordless is a great alternative IMO, but I'm also optimistic about newer alternatives like WebAuthn/Passkeys, which we are looking into supporting out-of-the-box. That's all I wanted to say. Great post, great lib, respect @pilcrowonpaper! 🎩 |
Beta Was this translation helpful? Give feedback.
-
My 2 cents as someone who has followed the development of Lucia but has never used it in a project I don't get why libraries are discouraging password authentication, it is by far the most popular method of authentication and the way to move away is not to persuade developers but rather users, I think every auth library should fully support it and the fact that it hard to pull of is all the more reason for libraries to support it so we don't have to worry about security |
Beta Was this translation helpful? Give feedback.
-
Maybe a little bit off-topic, but I'd love to see Lucia support WebAuthn/Passkeys. Is this possible with Lucia's keys? |
Beta Was this translation helpful? Give feedback.
-
As for the migration path, you have a few options:
Option 2 and 3 can be done with a few lines of SQL, but option 4 maybe a bit annoying (especially for SQLite) |
Beta Was this translation helpful? Give feedback.
-
I am mostly working on B2B & internal projects, IMHO, like it or not, password is still dominated in auth methods in these kinds of projects. Passwords are still having many upsides:
When using OAth, we are still using password but shift it complexity to OAuth provider with the price of freedom & privacy. Instead of discourage developer from password, maybe we can split passwords to it own package with their crucial modern features like password rules/strength, forgot/reset password, auto expiration, leak detection, suspicious behavior, ... It's a ton of work, but it still worth it. |
Beta Was this translation helpful? Give feedback.
-
Maybe this along with a cli would make it next level. |
Beta Was this translation helpful? Give feedback.
-
My personal opinion is that, especially in the long term, there is more value for Lucia to focus on documentation and guides, rather than the code itself. What does that mean? Rather than providing database-connected APIs for verification tokens, OAuth, passkeys, etc (ie. do 90% of the backend for you), it'll be more beneficial if we teach people how to implement auth using Lucia, Oslo, and their preferred ORM or query builder. Like, for OAuth, you just need like a few simple database queries. It takes minimum effort. You should be able to do that. And there lies the issue. If you want to implement auth by yourself, you should be ready to work with your database and put some effort into it. Lucia and Oslo will take care of the details, like session expirations, passkey validation, OAuth requests, and more. But you should at the very least understand the big picture. How OAuth works. How passkeys works. And the docs is the best place to teach that. Auth isn't easy. A library can only handle so much. And IMO we shouldn't hide that fact. |
Beta Was this translation helpful? Give feedback.
-
What you are writing makes a lot of sense @pilcrowonpaper. I am eager to see where it will go. My 2 cents: I think there is a big market for a low profile, generic and well documented solution. That said, on the other side of the spectrum you have - I believe - a big market for a full-fledged open source implementation which is - with some config and your own frontend - ready to ship. The downside is that it will be an opinionated solution, since you will make this for one set of libraries+framework to keep it maintainable. That said, with good documentation, this can be a very valuable example implementation for the community? My company would be happy to invest/donate in both if you are interested in such a plan. (I hope its clear enough, Its a bit tricky to be sure its well understandable 😄 ) |
Beta Was this translation helpful? Give feedback.
-
When we started to search for Auth Frameworks which support Vue + Nuxt, we didnt find many, which are production ready. There were some but they are bugged a lot - so not really safe to use. |
Beta Was this translation helpful? Give feedback.
-
@pilcrowonpaper So is there going to be a huge change to Lucia? Was planning on investing some time in figuring out how to implement Lucia with Next.js 14 since I am tired of wasting my time trying to do a work around to get next-auth sessions to be stored in the database. |
Beta Was this translation helpful? Give feedback.
-
@pilcrowonpaper first of all, very nice of you to start this thread! As a somewhat experienced but still noob developer, here's my opinion on the subject. (Keep in mind I consider myself naive on the subject of auth. Even if i've been coding for some years, I have very little professional experience.) Why I loved using Lucia?
Migration to an eventual v3Breaking changes?I would not care at all migrating (to a keyless implementation or whatever) if there is a guide provided. Since Lucia's doc is understandable, I have no doubt a migration guide would be perfect if you decide to go this route. Development / MaintenanceI would also be happy to migrate if it means you (as the main maintainer of the project) think you have good reasons for it, and it also means that you'll be happy to maintain it further. On the other side, i'd be pretty sad to learn that you would deprecate it after v3 because it went too far from you vision. It is important that you respect youself in the process. On the subject of Guides / TemplatesIn my experience, the hardest part was to figure out the auth (sign up, login, logout) workflow. Once all the bits put together, adding a database query here to create a user or verify a hashed password is just routine (let's be honest, i'm already making lots of complex db queries in my app...). Lucia really helped me pull off a simple template to build a mental model. Even just templates (or even maybe a checklist of crucial steps in order) without the library would have been a substantial help to me. What i'd like Lucia/Oslo to beOslo as primitive utilities is in its place imo. For Lucia, the best I can think of is something I can give a config to and that would return a collection of utilities to use around my app (much like it is designed now). I kind of think of it as a wrapper around Oslo for common tasks. I don't really care about details like database schemas or keys, as they are easy to pick up (and adopt) if it makes sense and make my dev life easier. I have trust in people like you to figure out the best approach, as I have never created an auth library as you did. Also, in my ideal world, all these common tasks could be overriden/extended to offer maximum flexibility. I saw someone mention Express/Koa in some comment and I think it is a nice way to think about it (mostly middlewares). Also SvelteKit architecture with load functions, actions and hooks is an awesome model for me. Perfect balance between opinionated (optimal patterns and workflows) and flexible (specific db queries, validation functions, sending TOTP requests to the user with X method as somebody else mentioned). Another rather random example, but I love the way svelte-headless-table implemented the 'plugin system*, making any instance unique and extensible while providing multiple possibilities and combinations. Library vs FrameworkNot an expert, but I sometimes see the debate of "is React a framework or library?". I don' t use React so I don't know at all, but my point is more about the comparison. From what i've seen : Library = you call it in your code (Oslo?) Framework = wrapper that call your code at the right moment (Lucia?) This is how I see things from my naive point of view! Hope my take on this can help you clarify the questions that are going around your head! ✌️ Edit : To add up on that, i'm also really fan of Vanilla JS solutions as it usually doable to use a JS solution in any framework (with a little bit of work of course) but much harder the other way around (ex: port a React lib to Svelte). |
Beta Was this translation helpful? Give feedback.
-
I know how to do database queries or fancy algorithms coding, but I don't know how to maintain an authentication flow that is actively up to date with the current best practices or at least the current standards of security in the given scope. The latter is the reason why I look for existing auth libraries for early stage projects, and what I would want from Lucia to provide. |
Beta Was this translation helpful? Give feedback.
-
My 2 cents:
My reasons for using Lucia:
IMO focus should be on a robust library that is forward compatible to always use best practices on account security and session management. Great work BTW, and thanks a lot! My first production app using Lucia is going online these days! |
Beta Was this translation helpful? Give feedback.
-
Just found this library. Wish I found it earlier. Amazing work. As others have already stated: Just keep it simple and maintained. No need to add complexity. And yeah, passwords are critical for most applications and they are not going anywhere, so built in utilities to help with password implementation would be helpful. What I'm confused about is that your guides explain very well how to set up password properly with email verification, preventing throttling etc. What is the issue exactly or am I missing something? What more needs to be done? Assuming you are not operating some financial institution, won't most apps just work fine by following those guides? |
Beta Was this translation helpful? Give feedback.
-
Certainly agree with this. If password auth is such an issue, why not make it CLEARER in the docs how to implement this properly and what steps to take instead of actively discouraging it and limiting the docs on this topic. And they can say as much as they want they arent purposely limiting the documentation on this topic, but they are by only including the base monimum required to make it work... In some cases not even that. Would rather like to see more complete docs. They only whay devs will implement this properly is by the "experts" who offer the library educating, especially new devs, how to do it properly. In some countries, email and password is the only option for auth. But by limiting the docs and access to this feature, these devs end up implementing auth strategies that are unusable in their target markets... Typically github auth in tuts, my users dont even know 99% of these auth providers. Anyway... Find it hard to learn and get better as a dev from the docs since there is little info there to help you in the right direction. Completely reliant on some guy on YouTube feeling like tackling this and making a video to help other devs with whatever since no one else will. |
Beta Was this translation helpful? Give feedback.
-
It will be interesting for me to watch how this project evolves. Having the ability to bring and swap out pieces as needed is a great feature. |
Beta Was this translation helpful? Give feedback.
-
Password auth needs to not be considered ‘an issue’ because it is the fundamental method which still dominates across wider settings. Awareness of challenges in implementing, good documentation on best practices and absolute avoids is a far more constructive approach rather than doing ‘don’t do it… too hard’ There are many industries and settings where it is simply not acceptable to trust or depend on someone else’s auth service |
Beta Was this translation helpful? Give feedback.
-
There are many legitimate use cases for password auth besides "legacy". Some projects cannot afford to be dependent on big tech, especially if they are in an undesired sector ie whistleblowing, self-hosting, political commentary etc. Some populations do not have stable email addresses or stable phone numbers (think cheap android burner phones with on-the-spot created gmail accounts, and then just recreated when the phone is replaced) |
Beta Was this translation helpful? Give feedback.
-
Hi @pilcrowonpaper, I read a couple of your posts in the Lucia repo, and while I haven't read all the comments in this discussion, I thought I'd share my opinion on some things I noticed:
I've worked with many developers over the years, and I am aware that not everybody values clear documentation and developer experience equally. However, having led the launch of two products, I can confidently say that documentation is probably as important as the product itself. I think that by prioritizing documentation and presenting the lib in a clear format with a clear focus and purpose, it'd be easier to draw a roadmap and prioritize what to work on internally. I am happy to offer some of my time to set up some guidelines on better documentation if you'd like. |
Beta Was this translation helpful? Give feedback.
-
Soon to be user here. I apologize for adding to this somewhat old discussion, but I liked the tone it opened with. I read a lot of comments on need / benefits / drawbacks of "password" based authentication. The approach I take, likely what many others do too, is use an in-house OpenID provider. This avoids any concerns of 3rd party providers while still offering all the benefits of Oauth. And on the plus side, I can use same provider to manage user roles. In my case, I set up a local keycloak server for the OpenID authentication provider. It was pretty easy to set up and straightforward to choose the authentication flows: user/pass/2FA and webauthn/passkey can be used as 2FA or a no-password login as well. Like @pilcrowonpaper said earlier, its good to use a tool that does one thing and does it well. I leave all the authentication and management of user roles etc to the Openid server. Background - I started a small project in authjs [1] but am now looking at lucia - and hopefully will be able to use it for my web app. Thank you @pilcrowonpaper for putting this together and doing so in an open, receptive and amicable way. I am now off to read more and learn what I need to do next to get started with lucia. [1] I found next-auth to work fine when it works, but when something doesn't work, it was a very significant problem . For example, when a working app was run behind a reverse proxy the auth part stopped working (likely my own fault) but this seems to have been a very long running issue for many. I tried most of the workarounds I could find but no luck. I also was unable to access roles passed back by keycloak in the JWT claims. |
Beta Was this translation helpful? Give feedback.
-
Short followup - and huge thank you to @pilcrowonpaper I have app running behind reverse proxy which authenticates using local keycloak server. i carefully walked through the docs (including the very helpful copenhagen book) and the sample code snippets which were hugely useful (especially for a C/C++/Python programmer learning ty/js as I go!). Enhancing the code to get the realm and client roles from keycloak was smooth as cream - and things just work and work as expected. Moving to production behind reverse proxy - just works. No hidden weird surprises. My advise for any authjs/next-auth folks - dont - stop now - use lucia instead - it is far and away superior and clean and you can use it do what you want/need. No gotchas. Big thank you again. |
Beta Was this translation helpful? Give feedback.
-
Hi, everyone.
The vibe I'm getting recently is that there's a disconnect between what I want out of Lucia, and what the community wants. An identity crisis if you will. I'm not sure how big the gap is, but it's definitely there. Part of the reason for that, I believe, is that while I have kept the project scope limited, I haven't clearly defined the goals of the project. I see that as a failure on my part as project lead. And my view on the library has definitely changed over time. The issue needs to be addressed, so let's talk about it.
Personally, I don't see auth as a whole hard. Just tedious and time consuming. So I don't want Lucia to handle a lot of things, just the annoying bits. And the most obvious target I see is session management. I think you'd agree here as well. And database adapters are a nice addition for small~medium sized projects too. So Lucia should definitely handle sessions and related database queries. Good.
Then comes the issue with authentication. There are mainly 2 approaches: OAuth and passwords. Either way, you interact with keys right now.
OAuth
First OAuth. I think having built-in providers that do all the requests is a big time saver. But the OAuth story in Lucia doesn't end there. You create a table for storing keys, and Lucia will handle database queries for getting existing users and creating keys. Is that necessary, and more importantly worth it? Yes, you get a nice API interface, but you give up on how those data is stored and you have to learn the concept of keys. Like, here's an example. The first one is with keys, and the second is without.
There are both equally readable and maintainable. And with the second one, you don't have to learn a Lucia-specific concept. Another benefit is that without the limitation keys, you have the options to store data that best fits your application:
github_user
tableThese are better options than storing every method into a single table.
Passwords
Next, password based auth. Unlike Auth.js, I don't want to make it harder to implement it. But I do want to discourage people from implementing it if they're not willing to put the care required to pull it off. Because here's the thing: email/password auth is tedious. It's not hard, but there's a lot of steps required to implement it correctly. And you're not making your password based auth any more secure by using Lucia's keys. Besides, if you're willing to take time to implement email verification, password reset tokens, and login throttling, keys aren't really making your work significantly easier.
You might think Lucia should handle stuff like verification tokens and login throttling. But, auth is inherently tied to your database, framework, and project structure. Lucia isn't the right abstraction level to implement it. For it to be realistic, Lucia would have to only support a single database driver/ORM, and maybe a single framework.
And similar to OAuth, if you just want basic password based auth for internal projects, it isn't hard:
The biggest benefit you get right now is that Lucia hashes password using the recommended algorithm + settings. But Lucia/Oslo can just provide an API just for that, without the database part or keys.
What do I want?
I want to remove keys. Maybe it's too radical. But I think it's a flawed concept that just isn't worth the trouble.
My original plan with v3 was to keep keys but only for OAuth, but maybe it's better to change rip off the bandaid.
But that's what I want from Lucia, taking into considering what's possible (session management) and what's not (a perfect library that handles every step of auth). I have to accept that it's not a personal project anymore. And that people hate breaking changes. So I want to ask the community; what do you want from Lucia?
Beta Was this translation helpful? Give feedback.
All reactions