Evaluating Next-Auth: The Efficacy of Next.js' Own Authentication Solution
Kamran Ahmed
Founder @ Oblivion | Making web3 so simple your grandma would use it (and probably teach you how)
Next.js has been a game-changer in the realm of web development since its inception, with industry giants like Twitch, Netflix, TikTok, and Spotify leveraging its enhanced features built upon the fundamental principles of Reactjs. These high-profile platforms all share a common need for robust authentication, a requirement that is universal across almost all web applications. And one of the reason’s why Next.js is the #1 Reactjs framework is because they have a state of the art authentication solution called ‘NextAuth’.
In this Article, we’re gonna talk about the current meta in the world of authentication, How and what NextAuth does in order to make things easier, How efficient of a solution it is and what are the major things NextAuth should work on next in order to become the first choice for developers when tackling authentication issues in Next.js.
Expected Learning Outcomes
Modern Practices for Authentication in Web Applications
It's safe to say that in 2024, the concept of authentication is widely understood. But what’s important is how authentication requirements and solutions have changed with time and what are the current most used practices for authentication solutions.
Initially with web applications, having a credential systems to access information was the go to, and having password encryption was the cherry on the cake. As years have gone by, there have been numerous frameworks and techniques developed to make this process much safter, improve user experience and make it easier for the developer to implement.
The initial developments included email verifications on signup, 2 factor authentications using emails/phone numbers on login, Biometric authentications using fingerprints, face recognitions and retina scans for high risk applications. Coming to recent past, Web apps have shifted to password-less solutions, majorly Oauth aka social logins in simpler terms.
Other than directly working on authentication mechanics, there have been numerous side techniques to improve user experience like extended sessions (remember me), resetting passwords and single sign-ons. Meanwhile there have been certain frameworks developed in order to make the life of web developers easier too. Famous frameworks including Google’s Firebase, AWS’ Amplify, Auth0, Hasura and others provide a low code solution to traditional authentication, Social providers, Multi factor authentications, Email verifications and Password resetting techniques.
Implementing and Exploring NextAuth: A Practical Example
NextAuth is an open source authentication solution for NextJs Applications, Helped developed by multiple of Vercel’s very own developers as well. They provide solution to traditional email/password, Password-less, magic links and Oauth authentications. They also provide serverless support using built in database adapters for the major Relational and Non relational databases. Last of all they follow all the required procedures and industry accepted security techniques with the addition of avoiding client side javascript and using signed, prefixed and server-only cookies.
To fully understand NextAuth’s efficacy we’re gonna use a practical example, where we’ll Learn to Setup NextAuth, Implement Signin and Signout functionalities, learn about NextAuth’s session management and protect certain routes.
NextAuth Setup:
To use NextAuth, you first need to install in in your Next.js project as a separate package, either using npm or yarn, based on your preference.
After installation, the first step is for you to add your next-auth environment variables in your .env file. NEXTAUTH_SECRET and NEXTAUTH_URL are mandatory environment variables, and there are some optional ones which depend on if you are using an Oauth providers for authentication i.e. Google.
Now if you are deciding on using an Oauth provider, in this case google, you will need to set a redirect URI as currently NextAuth doesn’t support signin with popup like the one Google provides.
Authentication handler:
Next we’ll need to create a file in our app router matching this exact directory structure,
app/api/auth/[...nextauth].js or pages/api/auth/[...nextauth].js
This file will contain your NextAuth handler, this handler will contain an array of providers you chose for your authentication and callback functions to help handle your session. In our case we’re gonna use both credential and google providers
Here we have 2 providers, a traditional credential one and a google auth provider. Using google is pretty simple we just have to provide the environment variables we set up beforehand, meanwhile it’s a little complex for the credentials as we need to either call our API or we need to connect to a database and check if our user exists, if it exists we return the user and use callbacks to handle our session object and JWT or if user doesn’t exist we return null and we can handle the error on our web page however we want.
In our frontend development, NextAuth helps us to access our user object and current session using a hook and async functions but by default when the session is created or updated the token is encrypted and stored in a cookie and in the user object, with the jwt callback we are storing the updated token into the user object. Meanwhile, the session callback is called whenever we access the current session, by default the only thing that is returned in the user object is email, name and image and if we want to access the token we need to explicitly define it like we did.
Session object type:
After defining the handler, we need to override the default type of our session object, this is not a mandatory step but if you want to access your token or any fields other than email, name or image from your user object this is a requirement.
领英推荐
NextAuth Provider:
We need to create a provider file where we can add our NextAuth provider and wrap it around to all the components in our Next.js project. This way our sessions can be accessible with in all the components.
After creating our provider.tsx file we will wrap this provider in the root of our application, which is the parent layout file, inside our app router directory. As it is the root of our application we can easily use any events, hooks and functions NextAuth provides with in all the rest of the components of our Next.js app.
We can also use this understand how NextAuth helps us get access to the current session in server components, we can use the function getServerSession(), this function either returns null if session doesn’t exists or returns the session object. we can use this for conditionally rendering components or any HTML based on our requirements in server components
SignIn and SignOut functions:
After we have completed our setup it’s time to move onto the actual authentication functions. Signing in and out using NextAuth is fairly simple. You can get the signIn and signOut functions from the package next-auth/react. For SignIn functions you need to pass the type of provider you are using, in this case we are using google and credentials so we are explicitly mentioning it when calling the signIn function. The Signout function is even more simple to use, just use it conditionally or on an event listener like it has been done here in the example.
We can also use this to get understanding of how can we access the session in client components. NextAuth provides a hook called useSession(), we can use this hook to get the session object and also a status field which contains the state of the session object, whether it’s being determined i.e “loading” or is it “unauthenticated” or “authenticated”. So this helps in waiting for the component to be mounted and session to be determined before accessing the session object.
Protected Routes:
Next.js has a option to create a middleware.tsx file in app directory, this enables you to intercept routing requests and determine if they should move forward, this is used to protect certain routes which you do not want to be accessible for certain conditions, mostly these conditions are either authentication or authorization related. Next.js simplifies this process as well, we just need to import default from next-auth/middleware and add all the routes into the config object which you want to be only accessible when authenticated.
NextAuth's Competence in Current Authentication Solutions:
NextAuth certainly provides alot of ease in implementing an authentication system for a Next.js application but it is not the only horse in the race between authentication frameworks. We will compare the offerings of NextAuth with an ideal authentication solution to determine how far off are they from perfecting their craft.
First of all is the session management in Next.js, For the people who have worked with Next.js know the hassle of syncing states of server components and client ones. If it needs to be done manually, we need to first create the session object(using a state management library or react context) in a client component, store the data in a cookie(preferably encrypted), Whenever the page refreshes, fetch the data from the cookie, decrypt it, populate the session object and keep it synced between client and server components. Now NextAuth does this very efficiently and we don’t need to write any code for it specifically. Using NextAuth we can access the session object using useSession hook in client components and the function getServerSession() in server components, and we don’t have to worry one bit about how it is handling the session in the background.
Another thing in which NextAuth excels is security, One of the USPs of their product is it being secure. NextAuth is one of the most secure authentication solutions available on web currently, starting with it using server-only cookies that are signed and prefixed, which means they can only accessed from the server and are protected from any tampering. Additionally from having all the basic security procedures including CSRF tokens on requests and auto revalidating sessions, they take advantage of Next.js being a full stack framework by not relying on client side javascript at all, preventing from cross-site scripting (X) attacks.
NextAuth with being specifically developed to solve authentication problems for Next.js applications, also happens to be open source. Which means it is in a process of being continuously debugged and developed. They have a large community on Github, Discord and Slack which means there are a lot of resources people available to help if you run into issues. This community also contributes to the ongoing improvement and expansion of NextAuth's features, ensuring it stays up-to-date with the latest best practices in authentication and security. Being open-source also promotes transparency, as anyone can review the code to ensure its reliability and security. Therefore, NextAuth not only provides a robust solution for authentication in Next.js applications but also fosters a dynamic and supportive ecosystem for developers.
Another positive aspect of NextAuth is their dedication of promoting the use of passwordless solutions. It is no secret that in years to come traditional authentication solutions using credentials are going to go extinct so NextAuth provides a set of different alternatives to choose from Single SignOns, magic links and 60+ Oauth providers. By supporting passwordless authentication, NextAuth helps to significantly reduce the risk of credential-related security breaches.
NextAuth's ability to function in a serverless environment is a significant advantage. It aligns perfectly with the modern trend of deploying applications in serverless architectures, which offer scalability, cost-effectiveness, and easier management. NextAuth provides this experience with the help of it’s widerange of adapters for the popular databases Whether you're using PostgreSQL, MongoDB, or even traditional relational databases like MySQL.
Another one of NextAuth’s appealing aspect is that it is entirely free to use. This opens up opportunities for developers and organizations of all sizes to implement robust, secure authentication in their applications without worrying about additional costs. It's particularly advantageous for small businesses, startups, and individual developers who are often working within tight budgets.
Areas for Improvement and Enhancement in NextAuth
Although NextAuth is a competitive solution to that provided by Google’s Firebase or AWS’s amplify, but there still are certain aspects of it which are still a pushback for a developer who has alot of different options to chose from. It being relatively newer, being specialized for a framework like Next.js which itself is under heavy development and it not being backed by a big tech organization like google or amazon contribute to the drawbacks but the trend of NextAuth’s development, like being built from scratch in 2020 in order to support serverless architectures and continuous updates show their positive approach to eliminate these drawbacks.
One big drawback to using NextAuth is it’s complex documentation, Although it seems pretty straightforward when reading, implementing it is another thing. There is a lot of boiler plate code with alot of configurations which might seem too complicated for someone working on it for the first time. The documentation of things required to completely build a proper authentication solution is split between many different sections and it’s really tough to learn them in proper order and understand their relation to each other.
Another thing which NextAuth lacks is that even though it cover the basics of authentication it isn’t a complete framework like firebase for example. Firebase has it’s own simple database to stores users, we can create users with it, signIn, signout, use email verification, use social logins, use multifactor authentication and it even provides ability to reset password with other email notifications. On the other hand you need to connect an external database with NextAuth, create a sign in handler and other than the signout functionality nothing else built in. With NextAuth not even providing a multifactor authentication it begs the question that is it really worth using it instead of a complete package like firebase.
It's clear that password-less solutions are poised to replace traditional credential-based authentication, the latter still remains the most widely used authentication method globally. This is where the challenge arises with NextAuth. If you have an authentication solution that requires token revalidation, refreshing of temporary tokens using a permanent one, or dealing with complex API response objects, it might be easier and more efficient to use a backend for handling authentication rather than using NextAuth. This is because NextAuth tends to add layers of complexity when dealing with intricate authentication scenarios. Managing these scenarios might require a deeper understanding of NextAuth's inner workings and could involve extensive customization.
While NextAuth's active development is a strength, it can also present challenges. With the tool being extensively developed and frequently updated to introduce new features and improvements, there are instances where these updates can cause breaking changes. This can cause existing applications to misbehave or totally stop working. This will unwillingly lead to the developer having to learn about the new changes, adjust their code and then test the changes which can lead to the development process slowing down.
Conclusion
NextAuth, with its powerful and feature-rich capabilities, is undeniably an excellent authentication framework for Next.js. However, it's also apparent that it may not always be the perfect fit for every scenario. Particularly in instances where unique or intricate authentication systems are already in place, where developers might opt for the efficiency of sticking to simpler, more traditional authentication methods rather than architecting a complex solution with NextAuth. That said, the trajectory of NextAuth suggests that it may not be long before it competes head-to-head with established players like Firebase. Moreover, as an open-source library, NextAuth invites contributions from developers around the world. This collaborative approach not only accelerates its growth but also allows developers play a part in shaping this tool ultimately benefiting the wider developer community.
Web3 Developer
2 个月informative keep sharing insights