Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discord provider is missing user.id in the session object #62

Open
FurStaku opened this issue Feb 10, 2024 · 21 comments
Open

Discord provider is missing user.id in the session object #62

FurStaku opened this issue Feb 10, 2024 · 21 comments

Comments

@FurStaku
Copy link

If I log the session, I only get this JSON Object back and the user.id is missing for some reason

Session Object :

{
  user: {
    name: 'staku',
    email: '[email protected]',
    image: 'https://cdn.discordapp.com/avatars/444560731300429844/28ef1f92c9bc92f919fa2ea5182ecb16.png'
  },
  expires: '2024-03-11T01:46:51.264Z'
}

auth.config.ts :

import Discord from '@auth/core/providers/discord';

import { defineConfig } from 'auth-astro';

export default defineConfig({
	providers: [
		Discord({
			clientId: import.meta.env.DISCORD_CLIENT_ID,
			clientSecret: import.meta.env.DISCORD_CLIENT_SECRET,
		}),
	],
});
@julianfbeck
Copy link

I have the same error using github. Did you find a solution?

@julianfbeck
Copy link

The soluzion is adding a callback inside the auth properties, thats add the userid

  ],
   callbacks: {
    session({ session, user }) {
      if (session.user) {
        session.user.id = user.id;
      }
      return session;
    }
  }

@FurStaku
Copy link
Author

The soluzion is adding a callback inside the auth properties, thats add the userid

  ],
   callbacks: {
    session({ session, user }) {
      if (session.user) {
        session.user.id = user.id;
      }
      return session;
    }
  }
[auth][error] JWTSessionError: Read more at https://errors.authjs.dev#jwtsessionerror
[auth][cause]: TypeError: Cannot read properties of undefined (reading 'id')
    at Object.session (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:18:31)
    at Module.session (file:///C:/.../auth/node_modules/@auth/core/lib/actions/session.js:35:52)
    at async AuthInternal (file:///C:/.../auth/node_modules/@auth/core/lib/index.js:35:24)
    at async Module.Auth (file:///C:/.../auth/node_modules/@auth/core/index.js:104:29)
    at async Module.getSession (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:56:20)
    at async eval (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:16:19)
    at async AstroComponentInstance.render (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:44:7)    
    at async Object.render (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:356:7)
    at async Module.renderChild (eval at instantiateModule (file:///C:/.../auth/node_modules/vite/dist/node/chunks/dep-G-px366b.js:54755:28), <anonymous>:36:5)
[auth][details]: {}

Doesn't work for me, I just get an error message when I try to log in, where should I add this?
Adding to auth.config.ts did not work.

@julianfbeck
Copy link

julianfbeck commented Mar 11, 2024

For me i added it like this to the auth config, but i only tested it for github, not for discord. t3-stack did the same, in order to add the user.id to every object

import GitHub from '@auth/core/providers/github';
import { DrizzleAdapter } from '@auth/drizzle-adapter';

import { db } from './src/utils/db';

import type { AuthConfig } from '@auth/core';
import { env } from '@/t3-env';

export default {
  adapter: DrizzleAdapter(db),
  providers: [
    GitHub({
      clientId: env.GITHUB_CLIENT_ID,
      clientSecret: env.GITHUB_CLIENT_SECRET
    })
  ],
  callbacks: {
    session({ session, user }) {
      if (session.user) 
        session.user.id = user.id;
      }
      return session;
    }
  }
} satisfies AuthConfig;

@Cocodrulo
Copy link

Plss solve this

@willnode
Copy link

I use this to get user ID

export default defineConfig({
  providers: [
    Credentials({
         ...
    }),
  ],
  callbacks: {
    session({ session, token }) {
      if (session.user && token?.sub) {
        session.user.id = token.sub;
      }
      return session;
    }
  }
})

@Cocodrulo
Copy link

But that does not retrieve the actual discord ID does it? it returns a unique identificatory number but not the actual discord ID right?

@willnode
Copy link

I think it is.

https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/discord.ts#L164-L168

After reading this repo code, I came to know that 'id' is forwarded as 'token.sub'

@Cocodrulo
Copy link

Cocodrulo commented Jun 30, 2024

No for what I can see. ID is now smth that not looks like the discord ID

image

@fearandesire
Copy link

For those struggling - the solution I used was a small function to extract it from the image URL.
The numbers after /avatars has the User ID, its standard with Discord.

/**
 * @summary Extracts the Discord User ID from the `image` field
 * Custom utility function designed to enable us to get a User ID from a session (using auth-astro)
 * @param {string} imageUrl
 * @returns {string}
 */
export function extractUserIdFromImage(imageUrl: string): string {
  const match = imageUrl.match(/avatars\/(\d+)\//);
  return match ? match[1] : '';
}

@Cocodrulo
Copy link

Cocodrulo commented Jul 9, 2024

And what if it has no avatar, then the image url is: 'https://cdn.discordapp.com/embed/avatars/0.png' @fearandesire

@fearandesire
Copy link

And what if it has no avatar, then the image url is: 'https://cdn.discordapp.com/embed/avatars/0.png' @fearandesire

Great point! I haven't come across this issue yet myself. That said, I just offered a solution that works for my needs. I'm not sure what to do in the event they don't have an avatar.

@fearandesire
Copy link

Following up, the solution provided by @willnode works! I explored this option for a site I recently launched, and the solution I provided prior was the cause of a silly bug as some users did not have avatars.

To clarify, for me -- this solution returns the User ID. I don't seem to get any UUID-like string as @Cocodrulo got here

@Cocodrulo
Copy link

I dont know why, sometimes token.sub gives the discord ID but other times it return thar strange UUID-like string. I was finally getting the discord ID and then suddenly token.sub was that kind of string again. I don't really understand.

@JusticeMatthew
Copy link

Any update on a fix for this issue or alternative work arounds?

I get the same issues above when using the callbacks, either user.id is not found or the token.sub is the weird UUID like value

Would love to continue using the library but I need that ID, there's really no point without it

@NicoToff
Copy link

NicoToff commented Aug 11, 2024

For those struggling - the solution I used was a small function to extract it from the image URL.
The numbers after /avatars has the User ID, its standard with Discord.

/**
 * @summary Extracts the Discord User ID from the `image` field
 * Custom utility function designed to enable us to get a User ID from a session (using auth-astro)
 * @param {string} imageUrl
 * @returns {string}
 */
export function extractUserIdFromImage(imageUrl: string): string {
  const match = imageUrl.match(/avatars\/(\d+)\//);
  return match ? match[1] : '';
}

I love this 😂 Very clever, I'm just concerned it will break if Discord randomly changes their avatar naming pattern.

Edit: And yes, as pointed out already, users with no avatar break this logic anyway

@FurStaku
Copy link
Author

For those struggling - the solution I used was a small function to extract it from the image URL. The numbers after /avatars has the User ID, its standard with Discord.

/**
 * @summary Extracts the Discord User ID from the `image` field
 * Custom utility function designed to enable us to get a User ID from a session (using auth-astro)
 * @param {string} imageUrl
 * @returns {string}
 */
export function extractUserIdFromImage(imageUrl: string): string {
  const match = imageUrl.match(/avatars\/(\d+)\//);
  return match ? match[1] : '';
}

problem here is that not everyone has a profile picture, so if you don't have one, it won't work because the avatar string is empty

@JusticeMatthew
Copy link

JusticeMatthew commented Aug 11, 2024

All right here is my hacky solution because I don't need access to the users email

import Discord from '@auth/core/providers/discord';
import { defineConfig } from 'auth-astro';

export default defineConfig({
  providers: [
    Discord({
      clientId: import.meta.env.DISCORD_CLIENT_ID,
      clientSecret: import.meta.env.DISCORD_CLIENT_SECRET,
      async profile(profile) {
        return {
          name: profile.username,
          email: profile.id,
          image: `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.png`,
        };
      },
    }),
  ],
});

gives me this from the session (verified that is my correct ID)

{
  user: {
    name: 'arknoodle',
    email: '223864942615461888',
    image: 'https://cdn.discordapp.com/avatars/223864942615461888/656ffa166759d7f24a73295a68ba023e.png'
  },
  expires: '2024-09-10T23:21:08.634Z'        
}

@ClyonsMT
Copy link

ClyonsMT commented Oct 2, 2024

If I want to add guild scope, to know which servers the user is on in Discord, how do I do it?

@Cocodrulo
Copy link

Cocodrulo commented Oct 4, 2024

All right here is my hacky solution because I don't need access to the users email

import Discord from '@auth/core/providers/discord';
import { defineConfig } from 'auth-astro';

export default defineConfig({
  providers: [
    Discord({
      clientId: import.meta.env.DISCORD_CLIENT_ID,
      clientSecret: import.meta.env.DISCORD_CLIENT_SECRET,
      async profile(profile) {
        return {
          name: profile.username,
          email: profile.id,
          image: `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.png`,
        };
      },
    }),
  ],
});

gives me this from the session (verified that is my correct ID)

{
  user: {
    name: 'arknoodle',
    email: '223864942615461888',
    image: 'https://cdn.discordapp.com/avatars/223864942615461888/656ffa166759d7f24a73295a68ba023e.png'
  },
  expires: '2024-09-10T23:21:08.634Z'        
}

Which version are u using?

@Cocodrulo
Copy link

If I want to add guild scope, to know which servers the user is on in Discord, how do I do it?

using the discord API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants