Product
Introducing Enhanced Alert Actions and Triage Functionality
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
remix-auth-discord
Advanced tools
Readme
The Discord strategy is used to authenticate users against a Discord account. It extends the OAuth2Strategy.
First go to the Discord Developer Portal to create a new application and get a client ID and secret. The client ID and secret are located in the OAuth2 Tab of your Application. Once you are there you can already add your first redirect url, f.e. http://localhost:3000/auth/discord/callback
.
You can find the detailed Discord OAuth Documentation here.
// app/session.server.ts
import { createCookieSessionStorage } from "@remix-run/node";
export const sessionStorage = createCookieSessionStorage({
cookie: {
name: "_session",
sameSite: "lax",
path: "/",
httpOnly: true,
secrets: ["s3cr3t"],
secure: process.env.NODE_ENV === "production",
},
});
export const { getSession, commitSession, destroySession } = sessionStorage;
// app/auth.server.ts
import { Authenticator } from "remix-auth";
import type { DiscordProfile, PartialDiscordGuild } from "remix-auth-discord";
import { DiscordStrategy } from "remix-auth-discord";
import { sessionStorage } from "~/session.server";
/**
* In this example we will remove the features of the guilds the user is in,
* so we have to create our own (slightly changed) type for the guilds.
* You might need to edit this in your use case.
*/
type CustomDiscordGuild = Omit<PartialDiscordGuild, "features">;
export interface DiscordUser {
id: DiscordProfile["id"];
displayName: DiscordProfile["displayName"];
avatar: DiscordProfile["__json"]["avatar"];
email: DiscordProfile["__json"]["email"];
locale?: string;
guilds?: Array<CustomDiscordGuild>;
accessToken: string;
refreshToken: string;
}
export const auth = new Authenticator<DiscordUser>(sessionStorage);
const discordStrategy = new DiscordStrategy(
{
clientID: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
callbackURL: "https://example.com/auth/discord/callback",
// Provide all the scopes you want as an array
scope: ["identify", "email", "guilds"],
},
async ({
accessToken,
refreshToken,
extraParams,
profile,
}): Promise<DiscordUser> => {
/**
* Get the user data from your DB or API using the tokens and profile
* For example query all the user guilds
* IMPORTANT: This can quickly fill the session storage to be too big.
* So make sure you only return the values from the guilds (and the guilds) you actually need
* (eg. omit the features)
* and if that's still to big, you need to store the guilds some other way. (Your own DB)
*
* Either way, this is how you could retrieve the user guilds.
*/
const userGuilds: Array<PartialDiscordGuild> = await (
await fetch("https://discord.com/api/v10/users/@me/guilds", {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
)?.json();
/**
* In this example we're only interested in guilds where the user is either the owner or has the `MANAGE_GUILD` permission (This check includes the `ADMINISTRATOR` permission)
* And not interested in the Guild Features.
* That's why we use the earlier created CustomDiscordGuild type now.
*/
const guilds: Array<CustomDiscordGuild> = userGuilds
.filter(
(g) =>
g.owner || (BigInt(g.permissions) & BigInt(0x20)) == BigInt(0x20),
)
.map(({ features, ...rest }) => {
return { ...rest };
});
/**
* Construct the user profile to your liking by adding data you fetched etc.
* and only returning the data that you actually need for your application.
*/
return {
id: profile.id,
displayName: profile.displayName,
avatar: profile.__json.avatar,
email: profile.__json.email,
locale: profile.__json.locale,
accessToken,
refreshToken,
guilds,
};
},
);
auth.use(discordStrategy);
// app/routes/login.tsx
import { Form } from "@remix-run/react";
export default function Login() {
return (
<Form action="/auth/discord" method="post">
<button>Login with Discord</button>
</Form>
);
}
// app/routes/auth.discord.tsx
import type { ActionFunction, LoaderFunction } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { auth } from "~/auth.server";
export let loader: LoaderFunction = () => redirect("/login");
export let action: ActionFunction = ({ request }) => {
return auth.authenticate("discord", request);
};
// app/routes/auth.discord.callback.tsx
import type { LoaderFunction } from "@remix-run/node";
import { auth } from "~/auth.server";
export let loader: LoaderFunction = ({ request }) => {
return auth.authenticate("discord", request, {
successRedirect: "/dashboard",
failureRedirect: "/login",
});
};
// app/routes/dashboard.tsx
import type { LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { auth } from "~/auth.server";
import type { DiscordUser } from "~/auth.server";
export let loader: LoaderFunction = async ({ request }) => {
return await auth.isAuthenticated(request, {
failureRedirect: "/login",
});
};
export default function DashboardPage() {
const user = useLoaderData<DiscordUser>();
return (
<div>
<h1>Dashboard</h1>
<h2>Welcome {user.displayName}</h2>
</div>
);
}
That's it, try going to /login
and press the Login button to start the authentication flow. Make sure to store all your Secrets properly and setup the correct redirect_url once you go to production.
FAQs
The Discord strategy is used to authenticate users against a Discord account. It extends the OAuth2Strategy.
The npm package remix-auth-discord receives a total of 1,451 weekly downloads. As such, remix-auth-discord popularity was classified as popular.
We found that remix-auth-discord demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
Security News
Polyfill.io has been serving malware for months via its CDN, after the project's open source maintainer sold the service to a company based in China.
Security News
OpenSSF is warning open source maintainers to stay vigilant against reputation farming on GitHub, where users artificially inflate their status by manipulating interactions on closed issues and PRs.