Hi I am new to nextjs and for authentication I am using next-auth. The users can log in using Google and when they are logged in and authenticated I want to get the access_token given by provider in this case Google. Although I can get that inside signIn callback function but is there a way to globally access that?
you can create the callbacks key in the nextAuth config as below to access your userId and access_token, as well.
callbacks: {
async session({ session, token, user }) {
session.user.id = token.id;
session.accessToken = token.accessToken;
return session;
},
async jwt({ token, user, account, profile, isNewUser }) {
if (user) {
token.id = user.id;
}
if (account) {
token.accessToken = account.access_token;
}
return token;
},
},
for next-auth v4 (and higher):
I had a problem accessing the access token inside the jwt callback, apparently, they have changed the schema and now accessToken is only stored in the Account table.
If you are storing user data in a database using an adapter, you could query the Account table inside the session function. In my case I was using the Prisma adapter and this worked fine for me:
async session({ session, token, user }) {
const getToken = await prisma.account.findFirst({
where: {
userId: user.id,
},
});
let accessToken: string | null = null;
if (getToken) {
accessToken = getToken.access_token!;
}
session.user.token = accessToken;
return session;
},
If you are using typescript and you want to return the token to the client, there is one more step you should do because it would complain otherwise,
Create a /types directory inside your source folder and add a next-auth-d.ts file inside of it.
You will extend the session interface here
import NextAuth, { DefaultSession } from "next-auth";
declare module "next-auth" {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: {
/** Oauth access token */
token?: accessToken;
} & DefaultSession["user"];
}
}
You can now access the session from clientside:
import React from "react";
import { useSession, signIn, signOut } from "next-auth/react";
type Props = {};
function ExampleComponent({}: Props) {
const { data: session } = useSession();
if (session) {
return (
<>
Access token {session.user.token} <br />
<button onClick={() => signOut()}>Sign out</button>
</>
);
}
return (
<>
Not signed in <br />
<button onClick={() => signIn("discord")}>Sign in with Discord</button>
</>
);
}
export default ExampleComponent;
NEXTAUTH_SECRET
is probably a good idea –
Margerymarget In Next Auth v4, the accessToken is now in the account object so you can get it with the jwt callback assign it to the token object and then assign it to session object using a callback as well.
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export const authOptions = {
providers: [
GithubProvider({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
}),
],
secret: process.env.JWT_SECRET,
callbacks: {
async jwt({token, account}) {
if (account) {
token = Object.assign({}, token, { access_token: account.access_token });
}
return token
},
async session({session, token}) {
if(session) {
session = Object.assign({}, session, {access_token: token.access_token})
console.log(session);
}
return session
}
}
}
next-auth-d.ts
snippet included in @Berke's answer if you're working in TypeScript. –
Doublebreasted for Credentials login
use callbacks like this
callbacks: {
jwt: async ({ token, user }) => {
user && (token.user = user)
return token
},
session: async ({ session, token }) => {
session.user = token.user
return session
}
}
then in page import
import { getSession ,useSession, signIn, signOut } from "next-auth/react";
and use this for get token
const { data: token, status } = useSession()
console.log(token)
for get sessin use this
const { data: session, status } = useSession()
console.log(session)
const { data: token, status }
and const { data: session, status }
won't give you two different results, but the same. This means token & session will be the same object. The colon in object destructuring just renames the given variable. –
Any You can access this using the getSession
method, which can be used server-side (i.e. in next.js methods like getServerSideProps
and client side (i.e. in your normal react components).
See: https://next-auth.js.org/getting-started/client#getsession
callbacks: {
async jwt({ token, user, account, profile, isNewUser }) {
if (account) {
console.log(account.id_token)
}
},
},
© 2022 - 2024 — McMap. All rights reserved.