Bot releases are visible (Hide)
Published by balazsorban44 almost 3 years ago
This post should cover the most important changes. https://balazsorban.com/blog/next-auth-v4
Published by github-actions[bot] almost 3 years ago
host
in getServerSession
(#3179) (e9ac11b)error
query param if set (#3141) (0d7d8da)secret
in production.session.jwt: boolean
option has been renamed to session.strategy: "jwt" | "database"
. The goal is to make the user's options more intuitive:strategy: "jwt"
: This is the default. The session is saved in a cookie and never persisted anywhere.strategy: "database"
: If an Adapter is defined, this will be the implicit setting. No user config is needed.strategy: "jwt"
: The user can explicitly instruct next-auth
to use JWT even if a database is available. This can result in faster lookups in compromise of lowered security. Read more about: https://next-auth.js.org/faq#json-web-tokens
Example:
session: {
- jwt: true,
+ strategy: "jwt",
}
Published by github-actions[bot] almost 3 years ago
Published by github-actions[bot] almost 3 years ago
jwt
option has been simplified and the NextAuth.js issued JWT is now encrypted by default.If you want to override the defaults, you can still use the encode
and decode
functions. These are advanced options and they should only be used if you know what you are doing.
The default secret generation comment has been removed in this PR, which will be added back in a separate one. Remember, that is only for developer convenience, it is highly recommended to always create your own secret for production.
Published by github-actions[bot] about 3 years ago
Published by github-actions[bot] about 3 years ago
jwks_uri
(#2813) (04fc3fd)picture
(#2851) (9e1eab0)OAuthConfig
generics (a2c4046)id
from user options in signinUrl
and callbackUrl
id (#2698) (819e97e)openid-client
options client
and jwks
(#2717) (50e6a64)Published by github-actions[bot] about 3 years ago
Published by github-actions[bot] about 3 years ago
callbackUrl
in Email Provider (#2574) (a9f699f)userinfo.params
optional (#2517) (65040dc)OAuthProviderType
(ed34534)staleTime
(#2613) (08349c3)callbacks
(#2173) (2833b66)profile
on signIn
events (#2356) (3312e53)logger
API (#2344) (acc9393), closes #2342 #1602
protection
to checks
(#2255) (6911dd9)useSession
(#2236) (a2e5afa)staleTime
(previously clientMaxAge
) has been removed. Check out refetchInterval
instead. It should cover most of the cases. If not, we can look into adding this back later on.user
scope to your configuration.prisma-legacy
is now gone. Use @next-auth/prisma-adapter
. Any features from the old adapter will be migrated over to the new one eventually. This is done so we can require the same default set of options from all the built-in providers, rather than allowing ambiguity on what an official adapter has to support.The TypeORM
adapter will probably be the only one migrated as-is, but in the future, we would like to break it down to lighter-weight adapters that only support single databases.
Adapters no longer have to return a getAdapter()
method, they can return the actual adapter methods instead. All the values previously being provided through the arguments of getAdapter
will now be available in a more digestible format directly in the concerning methods. This behavior was created so that connections could be handled more efficiently. Our review has shown that currently, the TypeORM adapter is the only one that does not handle connections out-of-the-box, so we are going to look into how we can create a wrapper/util function to make it work in the new version. For all other adapters, this will be a huge gain, as with this new API, methods are actually overrideable without creating a whole new custom adapter! π₯³
Example:
function MySlightlyCustomAdapter(...args) {
const adapter = AdapterFromSomeoneElse(...args)
adapter.someMethodIWantToModify = (...args) => {
// Much better implementation goes here.
}
return adapter
}
The following method names are changing:
- getSession
+ getSessionAndUser
This method now requires that you return both the user and the session as {user, session}
. If any of these could not be retrieved, you will have to return null
instead. (In other words, this must be a transaction.) This requires one less database call, improving the user session retrieval. Any expiry logic included in the Adapter before is now done in the core as well.
- createVerificationRequest
+ createVerificationToken
Better describes the functionality. This method no longer needs to call provider.sendVerificationRequest
, we are moving this into the core. This responsibility shouldn't have fallen to the adapter in the first place.
createVerificationToken
will now receive a VerificationToken
object, which looks like this:
interface VerificationToken {
identifier: string
expires: Date
token: string
}
The token provided is already hashed, so nothing has to be done, simply write it to your database. (Here we lift up the responsibility from the adapter to hash tokens)
- getVerificationRequest
+ useVerificationToken
Better describes the functionality. It now also has the responsibility to delete the used-up token from the database. Most ORMs should support retrieving the value while deleting it at the same time, so it will reduce the number of database calls.
- deleteVerificationRequest
This method is gone. See useVerificationToken
.
Most of the method signatures have been changed, have a look at the TypeScript interface to get a better picture.
Example:
- import Provider from "next-auth/providers"
- Providers.Auth0({...})
+ import Auth0Provider from "next-auth/providers/auth0"
+ Auth0Provider({...})
signOut
and updateUser
:// [...nextauth].js
...
events: {
- signOut(tokenOrSession),
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
- updateUser(user)
+ updateUser({ user })
}
error
event, it can also be an Error
instance (that is serializable by JSON.stringify
). If it is an object, an Error
instance will be available on metadata.error
, and message
will default to metadata.error.message
. This is done so that an error event always provides some kind of a stack to see where the error happened// [...nextauth.js]
import log from "some-logger-service"
...
logger: {
- error(code, ...message) {},
+ error(code, metadata) {},
- warn(code, ...message) {},
+ warn(code) {}
- debug(code, ...message) {}
+ debug(code, metadata) {}
}
state
option on OAuth providers is now deprecated. Use checks: ["state"]
instead.protections
is renamed to checks
, here is an example:- protection: ["pkce"]
+ checks: ["pkece"]
Furthermore, string values are not supported anymore. This is to be able to handle fewer cases internally.
- checks: "state"
+ checks: ["state"]
useSession
hook now returns an object. Here is how to accommodate for this change:- const [ session, loading ] = useSession()
+ const { data: session, status } = useSession()
+ const loading = status === "loading"
With the new status
option, you can test states much more clearly.
callbacks
method signatures are changing the following way:- signIn(user, account, profileOrEmailOrCredentials)
+ signIn({ user, account, profile, email, credentials })
- redirect(url, baseUrl)
+ redirect({ url, baseUrl })
- session(session, tokenOrUser)
+ session({ session, token, user })
- jwt(token, user, account, OAuthProfile, isNewUser)
+ jwt({ token, user, account, profile, isNewUser })
NOTE: You only need to define the params that you actually need (no more need for
_
params.)
This way, if you only need token
and account
in the jwt
callback, you can write:
jwt({ token, account }) {
if(account) {
token.accessToken = account.access_token
}
return token
}
react:
1. next-auth/client
is renamed to next-auth/react
.
2. In the past, we exposed most of the functions with different names for convenience. To simplify our source code, the new React specific client code exports only the following functions, listed with the necessary changes:
setOptions
: Not exposed anymore, use SessionProvider
propsoptions
: Not exposed anymore, use SessionProvider
propssession
: Rename to getSession
providers
: Rename to getProviders
csrfToken
: Rename to getCsrfToken
signin
: Rename to signIn
signout
: Rename to signOut
Provider
: Rename to SessionProvider
3. Provider
changes.
Provider
is renamed to SessionProvider
options
prop is now flattened as the props of SessionProvider
.keepAlive
has been renamed to refetchInterval
.- <Provider options={{clientMaxAge: 0, keepAlive: 0}}>{children}</Provider>
+ <SessionProvider refetchInterval={0}>{children}</SessionProvider>
4. It is now required to wrap the part of your application that uses useSession
into a SessionProvider
.
Usually, the best place for this is in your pages/_app.jsx
file:
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps }
}) {
return (
// `session` comes from `getServerSideProps` or `getInitialProps`.
// Avoids flickering/session loading on first load.
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
AzureADB2C
, you will need to update it to to AzureAD
There should be no other changes needed.Check out https://github.com/nextauthjs/adapters
The migration is super easy and has HUGE advantages for those not using TypeORM.
// [...nextauth].js
+ import TypeORMAdapter from "@next-auth/typeorm-legacy-adapter"
import NextAuth from "next-auth"
...
export default NextAuth({
- database: "yourconnectionstring",
+ adapter: TypeORMAdapter("yourconnectionstring")
})
Co-authored-by: Lluis Agusti [email protected]
Co-authored-by: Giovanni Carnel [email protected]
typeorm
, and nodemailer
are no longer dependencies added by default.adapter
configuration or a database
, you will need typeorm
. You could also check out @next-auth/typeorm-adapter
. In case you are using the Email provider, you will have to install nodemailer
(or you can use the choice of your library in the sendVerificationRequest
callback to send out the e-mail.)state: true
is already redundantprotection: "state
is the default value. state: false
protection: "state"
Published by github-actions[bot] about 3 years ago
Published by github-actions[bot] about 3 years ago
staleTime
(previously clientMaxAge
) has been removed. Check out refetchInterval
instead. It should cover most of the cases. If not, we can look into adding this back later on.Published by github-actions[bot] about 3 years ago
callbackUrl
in Email Provider (#2574) (a9f699f)user
scope to your configuration.Published by github-actions[bot] about 3 years ago
Published by github-actions[bot] about 3 years ago
prisma-legacy
is now gone. Use @next-auth/prisma-adapter
. Any features from the old adapter will be migrated over to the new one eventually. This is done so we can require the same default set of options from all the built-in providers, rather than allowing ambiguity on what an official adapter has to support.The TypeORM
adapter will probably be the only one migrated as-is, but in the future, we would like to break it down to lighter-weight adapters that only support single databases.
Adapters no longer have to return a getAdapter()
method, they can return the actual adapter methods instead. All the values previously being provided through the arguments of getAdapter
will now be available in a more digestible format directly in the concerning methods. This behavior was created so that connections could be handled more efficiently. Our review has shown that currently, the TypeORM adapter is the only one that does not handle connections out-of-the-box, so we are going to look into how we can create a wrapper/util function to make it work in the new version. For all other adapters, this will be a huge gain, as with this new API, methods are actually overrideable without creating a whole new custom adapter! π₯³
Example:
function MySlightlyCustomAdapter(...args) {
const adapter = AdapterFromSomeoneElse(...args)
adapter.someMethodIWantToModify = (...args) => {
// Much better implementation goes here.
}
return adapter
}
The following method names are changing:
- getSession
+ getSessionAndUser
This method now requires that you return both the user and the session as {user, session}
. If any of these could not be retrieved, you will have to return null
instead. (In other words, this must be a transaction.) This requires one less database call, improving the user session retrieval. Any expiry logic included in the Adapter before is now done in the core as well.
- createVerificationRequest
+ createVerificationToken
Better describes the functionality. This method no longer needs to call provider.sendVerificationRequest
, we are moving this into the core. This responsibility shouldn't have fallen to the adapter in the first place.
createVerificationToken
will now receive a VerificationToken
object, which looks like this:
interface VerificationToken {
identifier: string
expires: Date
token: string
}
The token provided is already hashed, so nothing has to be done, simply write it to your database. (Here we lift up the responsibility from the adapter to hash tokens)
- getVerificationRequest
+ useVerificationToken
Better describes the functionality. It now also has the responsibility to delete the used-up token from the database. Most ORMs should support retrieving the value while deleting it at the same time, so it will reduce the number of database calls.
- deleteVerificationRequest
This method is gone. See useVerificationToken
.
Most of the method signatures have been changed, have a look at the TypeScript interface to get a better picture.
Example:
- import Provider from "next-auth/providers"
- Providers.Auth0({...})
+ import Auth0Provider from "next-auth/providers/auth0"
+ Auth0Provider({...})
Published by github-actions[bot] about 3 years ago
Published by github-actions[bot] about 3 years ago
profile
on signIn
events (#2356) (3312e53)signOut
and updateUser
:// [...nextauth].js
...
events: {
- signOut(tokenOrSession),
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
- updateUser(user)
+ updateUser({ user })
}
ALL OAuth providers' profile
callback is expected to only return these fields by default from now on: id
, name
, email
, and image
at most. Any of these missing values should be set to null
.
The following new options are available:
authorization
(replaces authorizationUrl
, authorizationParams
, scope
)token
replaces (accessTokenUrl
, headers
, params
)userinfo
(replaces profileUrl
)These three options map nicely to the OAuth spec's three endpoints for
They all take the form of EndpointHandler
:
type EndpointRequest<C, R> = (
context: C & {
/** `openid-client` Client */
client: Client
/** Provider is passed for convenience, ans also contains the `callbackUrl`. */
provider: OAuthConfig & {
signinUrl: string
callbackUrl: string
}
}
) => Awaitable<R>
/** Gives granular control of the request to the given endpoint */
type AdvancedEndpointHandler<P extends UrlParams, C, R> = {
/** Endpoint URL. Can contain parameters. Optionally, you can use `params`*/
url?: string
/** These will be prepended to the `url` */
params?: P
/**
* Control the corresponding OAuth endpoint request completely.
* Useful if your provider relies on some custom behavior
* or it diverges from the OAuth spec.
*
* - warning **This is an advanced option.**
* You should **try to avoid using advanced options** unless you are very comfortable using them.
*/
request?: EndpointRequest<C, R>
}
/** Either an URL (containing all the parameters) or an object with more granular control. */
type EndpointHandler<P extends UrlParams, C = any, R = any> =
| string
| AdvancedEndpointHandler<P, C, R>
In case of authorization
, the EndpointHandler
can define the params
as AuthorizationParameters
Note:
authorization
does not implementrequest
yet. We will have to see if there is demand for it.
From now on, instead of using the ...
spread operator when adding a new built-in provider, the user is expected to add options
as a property at the end of the default config. This way, we can deep merge the user config with the default one. This is needed to let the user do something like this:
MyProvider({
clientId: "",
clientSecret: "",
authorization: { params: {scope: ""} }
})
So even if the default config defines anything in authorization
, only the user-defined parts will be overridden.
Published by github-actions[bot] over 3 years ago
logger
API (#2344) (acc9393), closes #2342 #1602
protection
to checks
(#2255) (6911dd9)error
event, it can also be an Error
instance (that is serializable by JSON.stringify
). If it is an object, an Error
instance will be available on metadata.error
, and message
will default to metadata.error.message
. This is done so that an error event always provides some kind of a stack to see where the error happened// [...nextauth.js]
import log from "some-logger-service"
...
logger: {
- error(code, ...message) {},
+ error(code, metadata) {},
- warn(code, ...message) {},
+ warn(code) {}
- debug(code, ...message) {}
+ debug(code, metadata) {}
}
state
option on OAuth providers is now deprecated. Use checks: ["state"]
instead.protections
is renamed to checks
, here is an example:- protection: ["pkce"]
+ checks: ["pkece"]
Furthermore, string values are not supported anymore. This is to be able to handle fewer cases internally.
- checks: "state"
+ checks: ["state"]