A lot has changed in Next.js since NextAuth 1.0 was released.
Now.sh, Vercel (formerly known Zeit), React and Node.js have also evolved a lot of the last couple of years.
This has made for a difficult moving target and so ,due the dramatic nature of those changes over the last year, feature development was paused on NextAuth (with the exception of minor maintenance updates for security).
With API routes introduced in Next.js 9.0 and Serverless deployments now the default on Now.sh (and widely supported on AWS, GPC and Azure) it's time for an update.
Authentication continues to be a pain point for a lot of folks. oAuth standardisation has improved, but common providers (Twitter, Facebook, Google, GitHub) all continue to have divergent implementations.
Lessons learned from 1.x and feedback dozens of issues and left by hundreds of people has gone into version 2.0 to try and take the pain out of setup and configuration, and to provide a solution that works for more people by improving the backend database support.
I'd like to thank everyone who raised issues, left feedback, helped out other folks when I didn't have time to get back to people, and to all those folks who raised pull requests (for all those that don't get merged in, please know they were not in vain, they've been invaluable!).
Version 2.0 is expected to drop sometime in May 2020, with releases will be published to next-auth@canary starting the first week of May. Feel free to ask questions or make requests below.
* NextAuth is not associated with Next.js or Vercel.
Version 2.0 is a complete re-write, designed from the ground up for serverless.
If you are familiar with version 1.x you will appreciate the much simpler and hassle free configuration, especially for provider configuration, database adapters and much improved Cross Site Request Forgery token handling (now enabled by default for next-auth routes only).
Additional options and planned features will be announced closer to release.
Configuration is much simpler and more powerful than in NextAuth 1.0, with both SQL and Document databases supported out of the box. There are predefined models for Users and Sessions, which you can use (or extend or replace with your own models/schemas).
To add next-auth to a project, create a file to handle authentication requests at pages/api/auth/[...slug.js]:
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import Adapters from 'next-auth/adapters'
const options = {
site: process.env.SITE_NAME || 'http://localhost:3000',
providers: [
Providers.Twitter({
clientId: process.env.TWITTER_CLIENT_ID,
clientSecret: process.env.TWITTER_CLIENT_SECRET,
}),
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET
}),
Providers.GitHub({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET
}),
],
adapter: Adapters.Default()
}
export default (req, res) => NextAuth(req, res, options)
All requests to pages/api/auth/* (signin, callback, signout) will now be automatically handed by NextAuth.
You can now use the can use the useSession() hook to see if a user is signed in.
import NextAuth from 'next-auth/client'
export default () => {
const [session, loading] = NextAuth.useSession()
return <>
{!loading && session && <p>Logged in as {session.user.name || session.user.email}.</p>}
{!loading && !session && <p>Not logged in.</p>}
</>
}
This is all the code you need to add support for signing in to a project!
Authentication with Server Side Rendering is also supported.
import NextAuth from 'next-auth/client'
export default ({ session }) => <>
{session && <p>You are logged in as {session.user.name || session.user.email}.</p>}
{!session && <p>You are not logged in.</p>}
</>
export async function getServerSideProps({req}) {
const session = await NextAuth.session({req})
return {
props: {
session
}
}
}
You can use this method and the useSession() hook together - the hook can be pre-populated with the session object from the server side call, so that it is avalible immediately when the page is loaded, and updated client side when the page is viewed in the browser.
You can also call NextAuth.session() function in client side JavaScript, without needing to pass a req object (it is only needed when calling the function from getServerSideProps or getInitialProps).
Authentication between the client and server is handled securely, using an HTTP only cookie for the session ID.
Important! The API for 2.0 is subject to change before release.
Configuration options are passed to NextAuth when initalizing it (in your /api/ route).
The only things you will probably need to configure are your site name (e.g. 'http://www.example.com'), which should be set explicitly for security reasons, a list of authentication services (Twitter, Facebook, Google, etc) and a database adapter.
An "Adapter" in NextAuth is the thing that connects your application to whatever system you want to use to store data for user accounts, sessions, etc. NextAuth comes with a default adapter that uses TypeORM so that it can be be used with many different databases without any configuration, you simply add the database driver you want to use to your project and tell NextAuth to use it.
To use SQLite in memory database (useful for development and testing, and to check everything is working):
npm i sqlite3NextAuth() in your API route.e.g.
adapter: Adapters.Default({
type: 'sqlite',
database: ':memory:'
}),
You can pass database credentials here securely, using environment variables in your application.
See the TypeORM configuration documentation for more details about supported options.
NextAuth now auto-generates simple, unbranded authentication pages for handling Sign in, Email Verification, callbacks, etc.
These are generated automatically with the appropriate sign in options based on the supplied configuration, but you can still create custom authentication pages if you would like to customize the experience.
npm info next-auth@beta.These pages are served from the API routes (e.g. /api/auth/signin) and are entirely server side generated with Preact to keep them as lightweight as possible, while still being easy to maintain.
While you can still create you own custom authentication up pages (and it will be possible to customise and/or disable these auto-generated pages) this means you don't need to do anything except set up a single API route as above, to get authentication working on your site.
The built in authentication pages are fully responsive, do not require JavaScript, have no external dependancies and use a tiny amount of embedded CSS. They can be safely embedded as an iFrame on another page. Only options you have enabled are displayed on the sign in page.

@iaincollins any chance for a canary code drop soon? Would love to see how you're looking to put this together.. (even if it's rough)
@gidich Possibly the end of this week if things go well (otherwise, I think the end of next week).
I'd like to do testing with the models across range of databases (MySQL, MongoDB, sqlite) before encouraging anyone to check it out. I'd like to try it out in production on a microsite to shake things down.
In the meantime, you can check out the development branch at https://github.com/iaincollins/next-auth/tree/next-auth-2 to get an idea of how things are doing.
I'll keep posting updates to this thread - both updating the main post and a summary of recent work in the comments.
useSession() hookNextAuth.Session()import NextAuth from 'next-auth/client'
export default () => {
const [session, loading] = NextAuth.useSession()
return <>
{!loading && session && <p>Signed in as {session.user.name || session.user.email}.</p>}
{!loading && !session && <p>Not signed in.</p>}
</>
}
This is all the code you need to add support for signing in to a project!
You can also call NextAuth.session(), both client and server side.
import NextAuth from 'next-auth/client'
export default ({ session }) => <>
{session && <p>Signed in as {session.user.name || session.user.email}.</p>}
{!session && <p>Not signed in.</p>}
</>
export async function getServerSideProps({req}) {
const session = await NextAuth.session({req})
return {
props: {
session
}
}
}
Although tagged as a beta release, it's really a developer preview release.
The beta releases should not be used in production, they will contain glaring bugs, may not be secure and there will be no upgrade path to future releases.
However, if you are interested in seeing how things are going and would like to provide early feedback or just kick the tires on the next version you can check it out.
Feedback is welcome, either here, or as regular issues - please mark them as being relevant to version 2.0.
Secure option, setting __Secure- and __Host- prefixes on cookie names (these can be customised) and signing of cookies.http://localhost:3000) for developer convenience./api/auth/signout.Cross Site Request Forgery protection was the focus of this release.
Improvements over NextAuth 1.0 include CSRF token protection for sign in (without pre-sessions), no need to persist CSRF tokens server side, cryptographic verification of token authenticity, and stricter default settings for cookies, especially the HTTP only, secure, host-only CSRF token.
The Double Submit Cookie method combined with the __Host- prefix and using a hash of the cookie value generated by the value combined with a secret known only to the server provides a reasonable starting point for protection against Cross Site Request Forgery attacks without negatively impacting the user experience or requiring the creation of server side sessions for clients that are not authenticated.
~There is an open question as to what the most appropriate behaviour for users should be in the event of a mismatch (i.e. what should be displayed to the client), which is pending seeing what the user experience is like in practice and further documentation is needed. Fortunately the approach taken makes it unlikely for mismatch errors to occur in practice.~
What happens when CSRF tokens are invalid is left up to individual routes, which are passed a csrfTokenValid boolean to simplify secure handling while delivering optimal user experince.
e.g. a POST request to /api/auth/signout does not contain a valid token (i.e. that matches the signed cookie in the HTTP headers) it simply sets a new cookie and redirects the client to make a GET request for /api/auth/signout which displays a sign out button in a secure form that does contains a valid token.
I followed up some the initial update for today with more refactoring, added sign out functionality, release as beta 10 and updated the post above.
Currently, these are the "missing critical features" that I consider are blocking release of 2.0:
I've managed to blitz through 2.0 in a few days and I don't anticipate any these being particularly difficult. I could probably complete them over the next couple of days and could release 2.0 early in a few days.
There are of course still other features missing to meet / exceed feature parity with NextAuth 1.0 and cover various use cases, but personally for me they are not as blocking:
Interested in feedback on the possibility of releasing early.
The current version of NextAuth 1.0 isn't viable for Next.js 9 or hosting on the now.sh anymore and is of limited use (and it will not be actively supported). With that in mind, I am leaning towards releasing 2.0 as soon as it is viable.
I am considering releasing it even without the email sign in flow (which would then follow later, but would essential the same way as the other providers) or username / password based logins.
Overall, I think it's going to be quicker and easier to address issues the sooner 2.0 is released, but the tradeoff is that some things on the wish list might take a bit longer if other things turn out to be more important to people in the short term.
A big difference with 2.0 is changes don't impact your entire application, and are restricted to the /api/auth route (and the route name is configurable), so it's a lot easier and safer to upgrade and roll out changes, so it really should be quicker to roll out features - but I'd also like to take the time with the email flow and roll out something that works really well (e.g. nice HTML email templates, secure token verification, etc).
Please feel free to vote up or down on this comment as a way to leave feedback, or leave your own comment below if you feel a particular way about releasing early with a more limited feature set (and building on it over time).
This looks like a very nice library and I want to integrate it into a project I'm starting, but is it possible to add custom providers?
is it possible to add custom providers?
It is! I was actually just talking about that in this thread, the documentation doesn't cover this yet, but this is a quick breakdown:
It comes with Twitter, GitHub, Google 'provider' profiles - with at least Facebook and maybe Keycloak to follow. Provider configs are passed in an array called providers:
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import Adapters from 'next-auth/adapters'
const options = {
site: process.env.SITE_NAME || 'http://localhost:3000',
providers: [
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET
}),
],
adapter: Adapters.Default()
}
export default (req, res) => NextAuth(req, res, options)
All these functions actually do is return a JSON object, with any options passed to the functions overriding the default values for that provider profile.
e.g. if you do console.log() on the response from Providers.Google() you get this:
{
id: 'google',
name: 'Google',
type: 'oauth',
version: '2.0',
scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email',
options: { grant_type: 'authorization_code' },
accessTokenUrl: 'https://accounts.google.com/o/oauth2/token',
requestTokenUrl: 'https://accounts.google.com/o/oauth2/auth',
authorizationUrl: 'https://accounts.google.com/o/oauth2/auth?response_type=code',
profileUrl: 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json',
profile: (profile) => {
return {
id: profile.id,
name: profile.name,
email: profile.email,
image: profile.picture
}
},
clientId: '',
clientSecret: ''
}
So, in theory you can pass your own configuration object here for an oAuth 1.0, 1.0A or 2.0 provider and it should work, as long as the options and URLs are correct.
If you want to use another oAuth provider, or you can't get one to work no matter what options you try (both the documentation and error logging for debugging could be better) I'm happy to help!
I'm also happy to include built-in support for common providers if folks are able to provide configuration options for them. :-)
@iaincollins nice! Going to try it out.
Okay, I tried it with Twitch and it works. But what's the callback URL that I have to add to the settings? Now I'm getting redirect mismatch when I use a custom URL so I suppose it's also provided by the library? I tried /api/auth/callback and /api/auth/twitch/callback too.
Edit: Deleted and changing my reply as I got the wrong end of the stick and answered the wrong question and just created confusion, please ignore that. ๐
If you go to /api/auth/providers you should see a list of what options for each provider (although it's a JSON object so will may to pretty print it to read it).
The path for the oAuth callback should be /api/auth/callback/twitch
The order of items in the path is slightly confusing (usually it would be as you've written it and I actually got stuck on this when I got it wrong configuring one of my own apps) but this order is a bit easier to support with the way Next.js API routes work, which is why it's like that.
PS: If you get a Twitch config working would love to have a copy of it and make it supported profile!
Thanks for this! Iโll be trying it out with https://github.com/danielcondemarin/serverless-next.js ๐
Thanks for this! Iโll be trying it out with https://github.com/danielcondemarin/serverless-next.js
Oh awesome! I'm a big fan of that serverless component and would appreciate feedback on if NexAuth works with it or if there are any issues.
v2 has very few dependencies but I worry that the default TypeORM adapter might be too much for serverless at the edge limits, if tree shaking isn't able to get the size down enough.
If that is the case, I'd be happy to consider creating an alternate lightweight adapter (maybe for a specific database?).
Oh awesome! I'm a big fan of that serverless component and would appreciate feedback on if NexAuth works with it or if there are any issues.
v2 has very few dependencies but I worry that the default TypeORM adapter might be too much for serverless at the edge limits, if tree shaking isn't able to get the size down enough.
If that is the case, I'd be happy to consider creating an alternate lightweight adapter (maybe for a specific database?).
Thanks! I will feedback for sure.
The Next core team recently released a new target called experimental-serverless-trace which Vercel Now uses for serverless deployments. For lambda deployments is better because unlike the serverless target it doesn't bundle node_modules for each serverless page. Instead you end up with a "shared" node_modules folder you can upload to a Lambda Layer for example.
I am working on adding support for it in sls-next.js which should solve the edge limit issues.
Thank you to @LoriKarikari for contributions and testing of both oAuth and database integration and for code contributions.
I'm thrilled to get external feedback that database integration seems to be working as expected (after a little bug squashing!) and to see that integration with additional oAuth services works.
Thanks folks have have left feedback here and elsewhere, I'm glad to hear it seems like v2 is going in the right direction and look forward to being able to getting to state where we have a production release in the coming days/weeks.
Just wanted to pop in and say this is looking great so far. Been trying it out with prisma2 for storing the sessions etc and works fine with a custom adapter.
Here's a recipe if anyone wants to try it
Given this schema.prisma:
model User {
id String @default(uuid()) @id
email String @unique
avatarUrl String?
name String?
sessions Session[]
accounts Account[]
createdAt DateTime @default(now())
}
model Session {
id String @default(uuid()) @id
userId String
user User @relation(fields: [userId], references: [id])
accessToken String @default(cuid()) @unique
accessTokenExpires DateTime
expires DateTime
createdAt DateTime @default(now())
}
model Account {
id String @default(uuid()) @id
userId String
user User @relation(fields: [userId], references: [id])
providerId String
providerType String
providerAccountId String @unique
refreshToken String?
accessToken String
accessTokenExpires DateTime?
createdAt DateTime @default(now())
}
You can make an adapter like this:
import { PrismaClient, User } from '@prisma/client'
interface Profile {
name: string
email: string
image: string
}
const PrismaAdapter = () => {
function debug(...args) {
if (process.env.NODE_ENV === 'development') console.log(...args)
}
let connection = new PrismaClient()
async function getAdapter() {
if (!connection) {
connection = new PrismaClient()
}
// Called when a user signs in
async function createUser(profile: Profile) {
debug('Create user account', profile)
return connection.user.create({
data: {
name: profile.name,
email: profile.email,
avatarUrl: profile.image,
},
})
}
async function updateUser(user: User) {
debug('Update user account', user)
return new Promise((resolve, reject) => {
// @TODO Save changes to user object in DB
resolve(true)
})
}
async function getUserById(id = '') {
debug('Get user account by ID', id)
return connection.user.findOne({ where: { id } })
}
async function getUserByProviderAccountId(providerId: string, providerAccountId: string) {
debug('Get user account by provider account ID', providerId, providerAccountId)
return connection.account
.findOne({
where: { providerAccountId },
})
.user()
}
async function getUserByEmail(email: string) {
debug('Get user account by email address', email)
return new Promise((resolve, reject) => {
// @TODO Get user from DB
resolve(false)
})
}
async function getUserByCredentials(credentials: string) {
debug('Get user account by credentials', credentials)
return new Promise((resolve, reject) => {
// @TODO Get user from DB
resolve(true)
})
}
async function deleteUserById(userId: string) {
debug('Delete user account', userId)
return new Promise((resolve, reject) => {
// @TODO Delete user from DB
resolve(true)
})
}
async function linkAccount(
userId: string,
providerId: string,
providerType: string,
providerAccountId: string,
refreshToken: string,
accessToken: string,
accessTokenExpires: string
) {
debug(
'Link provider account',
userId,
providerId,
providerType,
providerAccountId,
refreshToken,
accessToken,
accessTokenExpires
)
return connection.account.create({
data: {
accessToken,
refreshToken,
providerAccountId,
providerId,
providerType,
user: {
connect: {
id: userId,
},
},
accessTokenExpires,
},
})
}
async function unlinkAccount(userId: string, providerId: string, providerAccountId: string) {
debug('Unlink provider account', userId, providerId, providerAccountId)
return new Promise((resolve, reject) => {
// @TODO Get current user from DB
// @TODO Delete [provider] object from user object
// @TODO Save changes to user object in DB
resolve(true)
})
}
async function createSession(user: User) {
debug('Create session for user', user)
const date = new Date()
const sessionExpiryInDays = 30
const accessTokenExpiryInDays = 30
return connection.session.create({
data: {
accessTokenExpires: new Date(
date.setDate(date.getDate() + accessTokenExpiryInDays)
).toISOString(),
expires: new Date(date.setDate(date.getDate() + sessionExpiryInDays)).toISOString(),
user: {
connect: {
id: user.id,
},
},
},
})
}
async function getSessionById(id = '') {
debug('Get session by ID', id)
return connection.session.findOne({ where: { id } })
}
async function deleteSessionById(id: string) {
debug('Delete session by ID', id)
return connection.session.delete({ where: { id } })
}
return Promise.resolve({
createUser,
updateUser,
getUserById,
getUserByProviderAccountId,
getUserByEmail,
getUserByCredentials,
deleteUserById,
linkAccount,
unlinkAccount,
createSession,
getSessionById,
deleteSessionById,
})
}
return {
getAdapter,
}
}
export default PrismaAdapter
Iain, hi! Thank you very much! I've tried to use next-auth-2 with mongodb. I've installed mongodb driver and change adapter.config.js to this:
export default {
type: 'mongodb',
database: 'my-database2',
};
When I click the signin link, I get an error:

And in the database entry appears:

Iain, hi! Thank you very much! I've tried to use next-auth-2 with mongodb. I've installed mongodb driver and change adapter.config.js to this:
export default { type: 'mongodb', database: 'my-database2', };
When I click the signin link, I get an error:
It's probably related to the id field but I could be wrong.
@Fumler RE: Prisma driver.
That's great, thank you! There will probably be some breaking changes to the adapter in future, but they won't be that complicated - maybe a slight change in method names and response object.
If you want to raise an issue with this driver in - even a PR if you wanted to drop it in src/adapters/prisma.js (doesn't matter if not complete / tested!) - that would be really neat.
I think we can probably find a way to update how things work so that that loading (e.g. TypeORM or Prisma (or whatever) are loaded depending on what people choose, without making things too complicated. If not ,we can always split them out, but it would be interesting to have.
@nikitalk Thanks, I've turned your post into an issue as it sounds like a bug in the current beta!
@Fumler RE: Prisma driver.
That's great, thank you! There will probably be some breaking changes to the adapter in future, but they won't be that complicated - maybe a slight change in method names and response object.
If you want to raise an issue with this driver in - even a PR if you wanted to drop it in
src/adapters/prisma.js(doesn't matter if not complete / tested!) - that would be really neat.I think we can probably find a way to update how things work so that that loading (e.g. TypeORM _or_ Prisma (or whatever) are loaded depending on what people choose, without making things too complicated. If not ,we can always split them out, but it would be interesting to have.
I was considering doing a PR for it, but decided against it since the adapter won't work out of the box, it requires a very specific data model for prisma as you can see in the schema file. This might be better to include as something in the README or wiki or whatever as a recipe. But I'm not sure.
@iaincollins man you are a legend!
Been banging head with AWS Cognito/Amplify for a few days and realised how 100x complicated and poorly documented it was, and searching for a simple solution, and here you are with a great looking 2.0 about to drop.
Blocker for me would be lack of Credentials support e.g. sign up, sign in, forgot password, reset password etc.
I don't need a UI for those, just the endpoints or internal API.
Having built identity management func a few times, I certainly would prefer not to do it again, and the out of box Next.js integration is a winner here.
@iaincollins any news on customizing the sign-in pages yet?
Btw my first migration to v2 of next-auth worked flawlessly. Thanks a lot for the quick work!
npm run lint) and refactored to address code quality issues.Thanks to a PR from @Fumler, you can now use a Provider pattern to re-use context between components, reducing network calls and improving performance.
Adding NextAuth.Provider to _app.js in Next.js is very straightforward:
import NextAuth from 'next-auth/client'
export default ({ Component, pageProps }) => {
return (
<NextAuth.Provider>
<Component {...pageProps} />
</NextAuth.Provider>
)
}
Accessing a session in a component is unchanged; it 'just works' whether you are using NextAuth.Provider or not:
import NextAuth from 'next-auth/client'
export default () => {
const [session, loading] = NextAuth.useSession()
return <>
{loading && <p>Checking sessionโฆ</p>}
{!loading && session && <p>Signed in as {session.user.name || session.user.email}.</p>}
{!loading && !session && <p><a href="/api/auth/signin">Sign in here</p>}
</>
}
Thanks to @LoriKarikari we have a bunch new additional oAuth services in progress!
I had to do some work on the new Twitch flow as they changed the API in production less than a week after we added it. ๐คฆโโ๏ธ oAuth APIs change commonly enough that collectively they are a moving target.
With that in mind, I might move all the oAuth code natively into NextAuth which will reduce dependancy size even more (as we only need to implement what we need) and make addressing issues as they arise easier; right now we are having to monkey patch node-oauth to the point it's probably no longer work using it (but it's been invaluable so far and I'm very grateful for it).
I've started work in earnest on the email flows this week.
There isn't a huge amount do, and it's much improved over NextAuth 1.x.
This update has been delayed a few days was hoping to complete some work I sadly haven't had time for this week so far. Things are still on track for releasing 2.0 this month, but it looks like I'm probably going to wait till the email flow is complete first.
Having built identity management func a few times, I certainly would prefer not to do it again, and the out of box Next.js integration is a winner here.
Thanks, that's great to hear!
Just FYI longer term plans include a simple admin UI to manage users (search, create, update, delete, etc) and the option to control who can sign in / sign up more easily (e.g. must already have an account created in the DB for them, or based on their email domain, etc).
I don't actually see a reason NextAuth couldn't be used for non-Next.js apps in future, for those interested in a good auth solution generally.
e.g. An actual Next.js app might still handle sign in callbacks (etc) but as it is, it can be configured to allow any site on the same domain to call fetch('/api/auth/session') securely (though for optimal security it defaults to only supporting requests from the same host).
@iaincollins any news on customizing the sign-in pages yet?
No, I will probably leave supporting them till after email signup flow is done as it will probably be ultimately less work to do it that way, but the email signup flow is now in progress.
This should be super easy though! They will just be options when calling NextAuth in the /api/auth/* route, for example:
pages: {
signup: 'https://signup.example.com/',
error: '/error'
}
I expect that 'signup', 'signout', 'error', 'invite' (for email sign up flow) will all be available and can independently be defined (or not), as either absolute or relative URLs. When defined, any requests for those URLs on /auth/api/* will simply redirect to the specified location. Error pages will be passed error codes via query parameters (these will need documenting when they are settled on).
Btw my first migration to v2 of next-auth worked flawlessly. Thanks a lot for the quick work!
That's awesome! I'm trying to keep the beta releases decently stable, even if they are missing features. The current beta.22 is pretty good I think, but sometimes they are a little buggy (usually if I've just released it for testing and not spotted a bug until after it has gone out).
I know there are issues with getting the session on the first call to the client still (and erasing it properly in the client on logout), which will be resolved in future; the client behaviour needs a bit more edge case supporting complexity ported over from NextAuth 1.0.
PS: For user accounts created in v1 they will end up with some old objects on them that can be deleted (e.g. user.twitter = {}, user.facebook = { ... }) as these are stored in a separate table/collection now; but they won't do any harm as they are not used now.
Just FYI longer term plans include a simple admin UI to manage users (search, create, update, delete, etc) and the option to control who can sign in / sign up more easily (e.g. must already have an account created in the DB for them, or based on their email domain, etc).
I don't actually see a reason NextAuth couldn't be used for non-Next.js apps in future, for those interested in a good auth solution generally.
Obviously do what you want, but I have my own UI, separate from business logic,
and plan on using NextAuth code for out-of-box key workflow and provider support, and oob Next.js integration,
and don't want any of your opinionated UI ๐
Might be a good idea to make a core package with just the library which you can add to your app with custom UI. And create a separate package with pre-built UIs which are optional?
@TimNZ Thanks, that's helpful feedback. If it turns out that folks don't care about that no sense in lumbering everyone with it.
@LoriKarikari +1 That seems like a good approach.
Maybe the next-auth-example project could even have pages/admin folder, allowing folks to copy it and customise it if they want something like that.
@iaincollins yeah, I would focus on the core with custom UI first because I think more people will use custom UIs anyway. And if they need prebuilt UIs they can copy them from the example app. Like now there is no way yet for custom sign up pages which will be a deal breaker for a lot of people.
Yeah I think the prebuilt basic login / signup pages are a great feature for beginners, but anyone else would most likely be wanting to at least design their own pages.
@TimNZ Thanks, that's helpful feedback. If it turns out that folks don't care about that no sense in lumbering everyone with it.
Hey - if Forest Admin can raise $7m for an Admin Framework, why can't Next Auth be a great starter and maybe develop into something something, if that's of interest.
https://techcrunch.com/2019/11/28/forest-admin-raises-7-million-to-help-you-build-admin-panels/
https://www.forestadmin.com/
I abandoned Cognito, and not interested in Auth0 and others, because I envitably want to customise everything front and back.
Advantage of using NextAuth is I can do that with a solid foundation, and I get the serverless for scale/reliability for free.
@iaincollins again thanks so much for this.
Let me know how I can be of any help.
{{unsubscribe}} short code supported by mail service providers like sendpulse).const options = {
site: process.env.SITE,
providers: [
Providers.Email({
server: process.env.EMAIL_SERVER, // e.g. "smtp://user:[email protected]:25"
from: process.env.EMAIL_FROM
}),
Providers.Twitter({
clientId: process.env.TWITTER_ID,
clientSecret: process.env.TWITTER_SECRET
}),
Providers.Google({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET
}),
],
adapter: Adapters.Default(adapterConfig),
}
The goal of the default look and feel is a white labelled experience, it will be subject to further refinement prior to release.
The email is fully customisable with the default adapter, but you can also write your own adapter to handle email account creation and verification however you want.



I'm trying to drop the adapterConfig object / Adapters config entirely but it doesn't seem to be possible. No matter what I do its always looking for that getAdapter() function.
Anyway to drop that if you dont have any local auth method?
Btw keep up the great work! This is already behaving so much better than v1 ever did in my projects :)
@iaincollins damn you've been on a roll!
I'm trying to drop the adapterConfig object / Adapters config entirely but it doesn't seem to be possible. No matter what I do its always looking for that
getAdapter()function.Anyway to drop that if you dont have any local auth method?
Not right now; currently a database of some kind is always needed and used to store users and sessions, so a backend adapter is required (with the default version being TypeORM, as it supports a range of popular SQL and noSQL databases).
However, in a future update I'm considering providing the option to support a JWT token for those with use cases that don't need any kind of server side state. It could be done with minimal (and entirely backwards compatible) changes.
It would be possible to support a flow that verifies a user was signed in with a particular third party oAuth service and to make those sessions persistent entirely in the browser securely, using encryption; but the use cases for JWT tokens with no database backend at all are a bit limited.
However, they can be useful for read-only applications; for example to require users to have accounts with a specific provider at a specific domain (e.g. Google) and control access to a company dashboard.
You could also potentially make it possible white-list email domains or specific email address on the backend, to restrict access to certain pages or features to those users (e.g. to update changes which are then saved back somewhere like GitHub, which might be useful for a simple content management system).
Btw keep up the great work! This is already behaving so much better than v1 ever did in my projects :)
Great to hear its working well so far!
There is still a bunch of stuff to shake out but we are getting close now!
_tl;dr bug fixes, improved email sign in and impending release of v2_
?error= query parameter).You can now easily create your own fully customised email provider using source for the default email provider as an example.
You can customise the messages, use a different email sending library, push messages to a queue to be sent later by another service, check the email address against a whitelist before sending them (etc). This approach also makes it easier to debug problems with sending emails.
There are about 40 items on my TODO list before release.
Most of them fall into one of the following categories:
There are some things I'd like to do (like refactor oAuth handling to make it easier to debug) and automated testing of all flows, but they are not blockers.
I can get the first two done (database integration and token expiry) over the weekend. When they are done I will merge the current development release to the master branch (the exiting master will become v1/master so it's still technically possible to provided updates to those using it) and we may be looking at release of v2.0 next week (May 17-23).
As always, improvements, bug fixes and feedback are welcome at any point!
I'd encourage folks to raise issues - or make noise by commenting on existing issues - if they would like specific features or things addressed or have views on them (e.g. confusing, buggy, doesn't work as expected, not enough options).
I'll add the provider documentation tomorrow so you can merge it into the master branch.
@iaincollins holding off going deep until RC, as you are rapidly deving.
Your Adapter interface implementation allows everything I can think of, and it's easy to see how Credentials support will be added - code is easy to follow.
I'll be creating a custom Adapter for ArangoDB, and will likely use JWT for session token.
Great progress against a couple of outstanding bullet points.
Added Facebook support (@LoriKarikari)
Added Auth0 (@LoriKarikari)
Sessions now expire 30 days from the last time a user was active
This is configurable; they can also be set to to never expire, or to expire in the browser when the window is closed. How often the database is written to keep a session alive can also be configured.
Email sign in / verification links expire after 24 hours
This is also configurable.
Debug mode is now an option (defaults to off)
New documentation! (@ndom91 @LoriKarikari)
@ndom91 set us up with an awesome new documentation site powered by Docusaurus! at http://next-auth.js.org which will be the new homepage for the site.
The content is still work in progress, but this is incredibly valuable and great way to place to surface some of the documentation that @ndom91 and @LoriKarikari have been working on. I'm already finding it much easier to read and review and super useful, especially the search function.
The contributing guide has also been improved - now also updated and pinned as an issue.
Thanks for the amazing contributions! There is quite a bit of significant work done in the last few days, I look forward to another big update fairly soon.
Update:
Added some things we did since the last update that I forgot about!
Over the next few days I plan to resolve some missing options and improve some points of edge case handling then I'm going to work on testing database integration and documentation.
I'm not quite sure about getting everything ready for the end of this week but I don't think will overshoot it by much and I think we are still on track for the original target of end of the month and, thanks to contributions, a much more ambitious and better release than I'd imagined.
I think I really underestimated the amount of documentation that was needed , so I'm so grateful for all the work done there by both @ndom91 and @LoriKarikari and am looking forward to updating it with new info and examples!
In the v2 docs it says [...slug.js] which I think should be[...slug].js
Yup, thats a typo. Thanks for pointing it out ;)
Fixed: https://github.com/iaincollins/next-auth/commit/7ad11f73cd492b27697fa7950656a28017c7dc26
The Discord provider does not add the absolute URL to the redirect_uri query.
Discord oAuth Error:
{"redirect_uri": ["Not a well formed URL."]}
Config:
const options = {
site: process.env.BASE_URL,
providers: [
Providers.Discord({
clientId: process.env.DISCORD_OAUTH_ID,
clientSecret: process.env.DISCORD_OAUTH_SECRET,
})
],
database: {
type: 'mongodb',
database: process.env.MONGODB_URI,
}
}
oAuth URL:
https://discordapp.com/api/oauth2/authorize?response_type=code&prompt=consent&redirect_uri=%2Fapi%2Fauth%2Fcallback%2Fdiscord&scope=identify%20email&state=67ffc77&client_id=000000000000000
Hi, @Gr8z I just checked this out and it should work fine. I'm not able to reproduce this error. Which version are you using?
@LoriKarikari I am using the latest: 2.0.0-beta.43
Please disregard, the env variable change required a restart. It is working as expected.
@Gr8z haha okay, no worries! Are you getting an invalid grant_type error?
@iaincollins implemented next-auth and it works great, thanks.
I can see a bunch of enhancements I want to do in different areas.
Could you please create issues tagged to appropriate milestones (existing 2.0, or 2.1, 3.xx etc) so I can see what your roadmap is?
Don't want to duplicate efforts e.g. a pull request, and you're already doing it, or you have a strong opinion on something and you may not like my approach.
Hi, using 2.0.0-beta.45 results in the following error when logging in with Google.
ADAPTER_CONNECTION_ERROR { DataTypeNotSupportedError: Data type "timestamp" in "Account.accessTokenExpires" is not supported by "sqlite" database.
at new DataTypeNotSupportedError (/Users/emmenko/xxx/node_modules/typeorm/error/DataTypeNotSupportedError.js:7:28)
at /Users/emmenko/xxx/node_modules/typeorm/metadata-builder/EntityMetadataValidator.js:74:27
at Array.forEach (<anonymous>)
at EntityMetadataValidator.validate (/Users/emmenko/xxx/node_modules/typeorm/metadata-builder/EntityMetadataValidator.js:71:36)
at /Users/emmenko/xxx/node_modules/typeorm/metadata-builder/EntityMetadataValidator.js:42:74
at Array.forEach (<anonymous>)
at EntityMetadataValidator.validateMany (/Users/emmenko/xxx/node_modules/typeorm/metadata-builder/EntityMetadataValidator.js:42:25)
at Connection.buildMetadatas (/Users/emmenko/xxx/node_modules/typeorm/connection/Connection.js:497:33)
at Connection.<anonymous> (/Users/emmenko/xxx/node_modules/typeorm/connection/Connection.js:127:30)
at step (/Users/emmenko/xxx/node_modules/tslib/tslib.js:139:27)
at Object.next (/Users/emmenko/xxx/node_modules/tslib/tslib.js:120:57)
at fulfilled (/Users/emmenko/xxx/node_modules/tslib/tslib.js:110:62)
name: 'DataTypeNotSupportedError',
message:
'Data type "timestamp" in "Account.accessTokenExpires" is not supported by "sqlite" database.' }
@emmenko Try [email protected] :-)
_This will probably the last announcement before the release of 2.0_
We have merged 15 PRs in the last week and we've also been busy reviewing issues and responding to feedback. We've also been busy updating the documentation at https://next-auth.js.org
The last bit of work that remains before the release of 2.0 is additional testing to shake out issues and updating the documentation - which is in much better shape, but there are still some bits that are outdated or incomplete.
We would appreciate bug reports (and positive feedback!) as issues for MySQL, Postgres and MongoDB in particular!
The example site has more information on how to configure to configure a database.
Update for Monday, 26 May 2020
Get some sleep, @iaincollins , it's Tuesday already :rofl:
Awesome job, anyway! Thank you!!
I also wonder when he sleeps ๐
@iaincollins Not going to implement credentials login for the release? Just wondering what the roadmap is for that. Wanted to begin working on it bit the codebase changes so fast ๐ I'll leave it up to you and can help improving it afterwards.
I also wonder when he sleeps ๐
I actually joined a new team a couple of weeks ago so have had to time shift my work to evenings and a bit of time over lunch breaks :D
@iaincollins Not going to implement credentials login for the release? Just wondering what the roadmap is for that. Wanted to begin working on it bit the codebase changes so fast ๐ I'll leave it up to you and can help improving it afterwards.
So that's a great question and I'm sure a lot of folks are interested in that feature!
I am always super happy if folks want to work on features they are interested to get things earlier. I appreciate that is quite hard right now as there is a lot of refactoring, and some more refactoring that needs to happen to make things easier to follow and there could be better documentation for contributors.
I think support for credentials - which might be username / password, but it seems like could also include something like 2FA (e.g. text message, authenticator token, etc) - is something I've been thinking of targeting for 2.1, after code cleanup and maybe some other features (see JWT).
I'm also thinking of what changes might be appropriate to accommodate making email addresses optional - if that is a thing we want to support - and if these things might relate (e.g. what should the database structure look like for them).
I'm actually somewhat reluctant to add this feature as having passwords tends to be a footgun. It was supported in v1, but you had to do quite a bit of work yourself to actually do it, and that was somewhat by design.
The reason for my reluctance that is that it exposes people to risk - lots of people don't use a password manager still, and even when they do they often still use reuse passwords of their own choosing, meaning accounts can be compromised whenever there a password leak at another organisation.
However, I appreciate a lot of people either have situations where they need something like this, because they have an existing system that works that way already, because they want to be able to do things like add 2FA or because they feel their users have an expectation of using a password based login for their service. I also appreciate it's a very commonly requested feature.
With that in mind I agree it's worth doing, and worth doing well so it's as secure as it can be out of the box (e.g. hashing with bcrypt) and easily extendable to support good practices like 2FA.
On that note, another thing I'm keen to add in 2.1 is JWT support, so that sessions don't need to be stored in a database.
I'm quite keen on as has really interesting implications; if you don't need a session database, it's possible to have an authenticated service that doesn't require a database. This is very quick to set up and very well suited to Single Page Apps in React and to Serverless.
Example use cases:
I think we could do this without a major refactor, and am even tempted to make it the default behaviour if you don't specify a database (with perhaps options to specify callback functions for account creation and fetching sessions, so you can easily customise what goes into the JWT).
On that note, another thing I'm keen to add in 2.1 is JWT support, so that sessions don't need to be stored in a database.
That would be great yes!! ๐
stumbled upon this today after seeing the incomplete features from the nextjs-auth0 integrations
thank you for all the hard work, given that @Fumler has already created the Prisma recipe, and Vercel has seemed to move forward with partnering with Prisma, maybe it can be merged to the project?
thank you for all the hard work, given that @Fumler has already created the Prisma recipe, and Vercel has seemed to move forward with partnering with Prisma, maybe it can be merged to the project?
@djstein I would love that! Given API changes I suspect it might have broken slightly, but I saved it in a ticket and am tracking that in this issue #151 I don't have any experience with Prisma and haven't tried to look at it myself yet.
As I'm currently testing this I figured that redirecting users to home page (could be customized) when they have already logged in.And prevent login routes when already logged in.
As I'm currently testing this I figured that redirecting users to home page (could be customized) when they have already logged in.And prevent login routes when already logged in.
Oh absolutely! This isn't actually being tracked in an issue, and I didn't mention it above, but has been discussed in some recent pull requests.
There will be additional functionality in the NextAuth.js client (similar to NextAuth v1), including signin() and signout() functions which you can just add to an onClick handler on a button.
They will take care of things like preserving the current page URL, so that the user is sent back to the right place after signing in or out - and so people don't have to interact with the default sign out page, which is really just intended as a fallback for clients without JavaScript.
I'm loving this project @iaincollins has done some outstanding work and really found a critical part of the nextjs stack we're missing. Thank you so much to @iaincollins and everyone in this thread for the long hours and hard work you're poured into this.
My side project involves Next.js, Discord, Paypal but critically https://fauna.com/ to act as a GraphQL server for not only the backend API calls inside Next.js but also the frontend. JWT looks like a match made in heaven as a simple lambda to manage this conversion would be ๐ . I would imagine this would create a pretty nice future proof stack.
@eknowles Thanks! I would love you to follow up with that as an issue.
I think both Fauna and Prisma are great candidates for first class support in future.
JWT support is now released, but we will need to figure out how to update it to work for everyone and I would love your feedback on that specifically (it would be great as a new issue).
Last update to this thread:
Thank you everyone for your feedback!
We are very close to moving out of beta and releasing ~on time~ only slightly later than planned โ with an amazing feature list for 2.0!
As this has grown quite long and things have changed during the beta, to make things easier to follow I'm closing this thread so I don't miss anything (and so that you don't all get spammed with old info) and and asking if you can move to the Release Candidate thread that just went up:
NextAuth 2.0 - Release Candidate
Thanks again for all your feedback and contributions! Please keep them coming.
Most helpful comment
Get some sleep, @iaincollins , it's Tuesday already :rofl:
Awesome job, anyway! Thank you!!