Created
April 12, 2021 12:53
-
-
Save ariscript/e0a92fb531a51c6cd81ff14ea5b15ef9 to your computer and use it in GitHub Desktop.
Discord "identify guilds" NextAuth.js implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import NextAuth from "next-auth"; | |
import Providers from "next-auth/providers"; | |
export default NextAuth({ | |
session: { | |
jwt: true, | |
}, | |
callbacks: { | |
jwt: async (token, user, account, profile) => { | |
// adding profile items to the token | |
if (user) { | |
token.profile = profile; | |
token.accessToken = account.accessToken; | |
token.refreshToken = account.refreshToken; | |
} | |
return Promise.resolve(token); | |
}, | |
// @ts-ignore | |
session: async (session, token) => { | |
// copy token information into session | |
// @ts-ignore | |
session.user.accessToken = token.accessToken; | |
// @ts-ignore | |
session.user.refreshToken = token.refreshToken; | |
// @ts-ignore | |
session.user.profile = token.profile; | |
// add user's guilds into session | |
const res = await fetch( | |
"https://discord.com/api/v8/users/@me/guilds", | |
{ | |
// @ts-ignore | |
headers: { Authorization: `Bearer ${token.accessToken}` }, | |
} | |
); | |
const data = await res.json(); | |
// @ts-ignore | |
session.user.profile.guilds = data; | |
return session; | |
}, | |
}, | |
// configure Discord provider | |
providers: [ | |
Providers.Discord({ | |
clientId: process.env.DISCORD_ID, | |
clientSecret: process.env.DISCORD_SECRET, | |
scope: "identify guilds", | |
// @ts-ignore | |
profile(profile) { | |
return profile; | |
}, | |
}), | |
], | |
}); |
Okay here is an update, It still doesn't work but I got it to produce a different error
import NextAuth from "next-auth";
import DiscordProvider from "next-auth/providers/discord";
export default NextAuth({
session: {
//@ts-ignore
jwt: true,
},
callbacks: {
//@ts-ignore
jwt: async ({ token, user, account, profile }) => {
if (user) {
token.profile = profile;
token.accessToken = account?.accessToken;
token.refreshToken = account?.refreshToken;
}
return Promise.resolve(token);
},
// @ts-ignore
session: async ({ session, token }) => {
// @ts-ignore
session.accessToken = token.accessToken;
// @ts-ignore
session.refreshToken = token.refreshToken;
// @ts-ignore
session.user = token.profile;
const res = await fetch(`https://discord.com/api/v10/users/@me/guilds`, {
headers: {
Authorization: `Bearer ${token.accessToken}`,
},
});
const data = await res.json();
// @ts-ignore
session.user.profile.guilds = data;
return session;
},
},
// Configure one or more authentication providers
providers: [
DiscordProvider({
// @ts-ignore
clientId: process.env.DISCORD_CLIENT_ID,
// @ts-ignore
clientSecret: process.env.DISCORD_CLIENT_SECRET,
authorization: {
params: {
scope: "identify guilds email connections",
},
},
profile(profile) {
return profile;
},
// ...add more providers here
}),
],
});
[next-auth][error][JWT_SESSION_ERROR]
https://next-auth.js.org/errors#jwt_session_error Cannot set properties of undefined (setting 'guilds') {
message: "Cannot set properties of undefined (setting 'guilds')",
stack: "TypeError: Cannot set properties of undefined (setting 'guilds')\n" +
' at Object.session (webpack-internal:///(api)/./pages/api/auth/[...nextauth].ts:41:41)\n' +
' at processTicksAndRejections (node:internal/process/task_queues:96:5)\n' +
' at async Object.session (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next-auth/core/routes/session.js:56:26)\n' +
' at async NextAuthHandler (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next-auth/core/index.js:158:27)\n' +
' at async NextAuthNextHandler (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next-auth/next/index.js:23:19)\n' +
' at async /home/container/projects/analog-tsx/apps/dashboard/node_modules/next-auth/next/index.js:59:32\n' +
' at async Object.apiResolver (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next/dist/server/api-utils/node.js:366:9)\n' +
' at async DevServer.runApi (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next/dist/server/next-server.js:481:9)\n' +
' at async Object.fn (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next/dist/server/next-server.js:735:37)\n' +
' at async Router.execute (/home/container/projects/analog-tsx/apps/dashboard/node_modules/next/dist/server/router.js:247:36)',
name: 'TypeError'
}
This is what worked for me, I was able to get all the users guilds.
// [...nextauth].ts
callbacks: {
async jwt({ token, account, profile }) {
if (account) {
token.accessToken = account.access_token;
// @ts-ignore
token.id = profile.id;
}
return token;
},
async session({ session, token, user }) {
// @ts-ignore
session.accessToken = token.accessToken;
// @ts-ignore
session.user.id = token.id;
return session;
},
},
// Next Page
export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await unstable_getServerSession(
context.req,
context.res,
authOptions
);
if (session) {
const guildsRes = await fetch("https://discord.com/api/users/@me/guilds", {
headers: {
// @ts-ignore
Authorization: `Bearer ${session.accessToken}`,
},
});
const guilds = await guildsRes.json();
const guildOwners = guilds && guilds.filter((guild: any) => guild.owner);
return {
props: {
session,
guilds: guildOwners ,
},
};
}
return {
redirect: {
destination: "/",
permanent: false,
},
};
};
Thanks, I got this working yesterday by doing something similar
// [...nextauth].ts
import NextAuth from "next-auth";
import DiscordProvider from "next-auth/providers/discord";
export const authOptions = {
// Configure one or more authentication providers
providers: [
DiscordProvider({
// @ts-ignore
clientId: process.env.DISCORD_CLIENT_ID,
// @ts-ignore
clientSecret: process.env.DISCORD_CLIENT_SECRET,
authorization: {
params: {
scope: "identify guilds email connections",
},
},
profile(profile) {
console.log(profile);
if (profile.avatar === null) {
const defaultAvatarNumber = parseInt(profile.discriminator) % 5;
profile.image_url = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNumber}.png`;
} else {
const format = profile.avatar.startsWith("a_") ? "gif" : "png";
profile.image_url = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
}
return {
id: profile.id,
name: profile.username,
discriminator: profile.discriminator,
image: profile.image_url,
accentColor: profile.accentColor,
};
},
// ...add more providers here
}),
],
callbacks: {
//@ts-ignore
jwt: async ({ token, account, profile }) => {
if (account) {
token.accessToken = account.access_token;
token.tokenType = account.token_type;
}
if (profile) {
token.profile = profile;
}
return token;
},
// @ts-ignore
session: async ({ session, token }) => {
// @ts-ignore
session.accessToken = token.accessToken;
// @ts-ignore
session.refreshToken = token.refreshToken;
// @ts-ignore
session.tokenType = token.tokenType;
// @ts-ignore
session.discordUser = token.profile;
// @ts-ignore
return session;
},
},
};
// @ts-ignore
export default NextAuth(authOptions)
// page
export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await unstable_getServerSession(
context.req,
context.res,
authOptions
);
const guildFetch = await fetch(
`https://discord.com/api/v10/users/@me/guilds`,
{
headers: {
// @ts-ignore
Authorization: `Bearer ${session?.accessToken}`,
},
}
);
const guilds = await guildFetch.json();
console.log(session)
return {
props: {
guilds,
},
};
};
https://github.com/ana-log/analog-tsx repo im making that is a template that allows you to make discord bots with a nextjs dashboard
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[next-auth][error][JWT_SESSION_ERROR]
https://next-auth.js.org/errors#jwt_session_error Cannot read properties of undefined (reading 'profile') {
message: "Cannot read properties of undefined (reading 'profile')",
stack: "TypeError: Cannot read properties of undefined (reading 'profile')\n" +
' at Object.session (webpack-internal:///(api)/./pages/api/auth/[...nextauth].ts:28:34)\n' +
' at Object.session (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next-auth\core\routes\session.js:56:42)\n' +
' at async NextAuthHandler (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next-auth\core\index.js:158:27)\n' +
' at async NextAuthNextHandler (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next-auth\next\index.js:23:19)\n' +
' at async C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next-auth\next\index.js:59:32\n' +
' at async Object.apiResolver (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next\dist\server\api-utils\node.js:366:9)\n' +
' at async DevServer.runApi (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next\dist\server\next-server.js:481:9)\n' +
' at async Object.fn (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next\dist\server\next-server.js:735:37)\n' +
' at async Router.execute (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next\dist\server\router.js:247:36)\n' +
' at async DevServer.run (C:\Users\BossDaily\Documents\Repos\DiscordBots\Typescript\analog-tsx\apps\dashboard\node_modules\next\dist\server\base-server.js:347:29)',
name: 'TypeError'
}