Important: This is the documentation for the upcoming Feathers v5 (Dove). See for the current version.

# Discord

Discord login can be initialized like any other OAuth provider by adding the app id and secret to config/default.json:

  "authentication": {
    "oauth": {
      "discord": {
        "key": "<App ID>",
        "secret": "<App Secret>",
        "scopes": ["identify email"]

Protip: A list of all available Discord scopes can be found here (opens new window)

# Application client and secret

The client id (App ID) and secret can be found here (opens new window): Discord App

Now add this to your src/authentication.ts:

import {OAuthProfile, OAuthStrategy} from "@feathersjs/authentication-oauth";
import {AuthenticationRequest} from "@feathersjs/authentication";
import axios, {AxiosRequestConfig} from 'axios'
import {ServiceAddons} from '@feathersjs/feathers';
import {AuthenticationService, JWTStrategy} from '@feathersjs/authentication';
import {LocalStrategy} from '@feathersjs/authentication-local';
import {expressOauth} from '@feathersjs/authentication-oauth';
import {Application} from './declarations';

export default function (app: Application) {
  const authentication = new AuthenticationService(app);

  authentication.register('jwt', new JWTStrategy());
  authentication.register('local', new LocalStrategy());
  authentication.register('discord', new DiscordStrategy());

  app.use('/authentication', authentication);

export default class DiscordStrategy extends OAuthStrategy {
  async getProfile(authResult: AuthenticationRequest) {
    // This is the OAuth access token that can be used
    // for Discord API requests as the Bearer token
    const accessToken = authResult.access_token;
    const userOptions: AxiosRequestConfig = {
      method: 'GET',
      headers: {'Authorization': `Bearer ${accessToken}`},
      url: ``,
    const {data} = await axios(userOptions);
    return data;

  async getEntityData(profile: OAuthProfile) {
    // `profile` is the data returned by getProfile
    const baseData = await super.getEntityData(profile);
    if (profile.avatar == null) {
      profile.avatar = ''
    } else {
      const isGif = profile.avatar.startsWith('a_');
      profile.avatar = `${profile['id']}/${profile['avatar']}.${isGif ? 'gif' : 'png'}`
    return {
      username: profile.username,
      avatar: profile.avatar,

If you don't need the avatar then you can simply remove the lines of code. If the user doesn't have an avatar then we will set it to Discord's default avatar.

Anything unclear or missing? Get help (opens new window) or Edit this page (opens new window)

Last Updated: 8/3/2020, 7:12:20 PM