remix-auth-socials
Version:
A collection of social media strategies for remix-auth
250 lines (196 loc) ⢠6.95 kB
Markdown
# Remix Auth Socials
WARNING: V3 Drops outdated packages that dont work with RR7. So V3 is considered broken / beta / use at your own risk
I have started the process of updating some and moving them temporarily into the package to provide access to RR7. I dont maintain this super often but if you want to PR one of the others feel free.
Currently Unavailable in V3:
ā Discord
ā Linkedin
ā X / Twitter
Facebook and Google are untested as of yet
> A collection of Remix Auth strategies for Oauth2 Social logins.
It's rare to see only one social login button, and no one likes a big package.json so here we are š
Remix auth socials collates community Oauth packages in a way that allows you to set up multiple social logins with ease.
## The Collection:
Please visit the repo's of each package to understand the specifics on their usage, and raise issues.
[remix-auth-discord](https://github.com/JonnyBnator/remix-auth-discord) - By [Jonny](https://github.com/JonnyBnator)
[remix-auth-facebook](https://github.com/manosim/remix-auth-facebook) - By [Manos](https://github.com/manosim)
[remix-auth-github](https://github.com/sergiodxa/remix-auth-github) - By [Sergio](https://github.com/sergiodxa)
[remix-auth-google](https://github.com/pbteja1998/remix-auth-google) - By [Bhanu](https://github.com/pbteja1998)
[remix-auth-microsoft](https://github.com/juhanakristian/remix-auth-microsoft) - By [Juhana](https://github.com/juhanakristian)
[remix-auth-twitter](https://github.com/na2hiro/remix-auth-twitter) - By [na2hiro](https://github.com/na2hiro)
[remix-auth-linkedin](https://github.com/Lzok/remix-auth-linkedin) - By [Lzok](https://github.com/Lzok)
## Supported runtimes
All strategies will support cloudflare
| Runtime | Has Support |
| ---------- | ----------- |
| Node.js | ā
|
| Cloudflare | ā
|
## How to use
### Setup your routes
To begin we will set up a dynamic route, that can handle each social on the fly
```tsx
// app/routes/auth/$provider.tsx
import { ActionArgs, redirect } from '@remix-run/node';
import { authenticator } from '~/server/auth.server';
export let loader = () => redirect('/login');
export let action = ({ request, params }: ActionArgs) => {
return authenticator.authenticate(params.provider, request);
};
```
```tsx
// app/routes/auth/$provider.callback.tsx
import { LoaderArgs } from '@remix-run/node';
import { authenticator } from '~/server/auth.server';
export let loader = ({ request, params }: LoaderArgs) => {
return authenticator.authenticate(params.provider, request, {
successRedirect: '/dashboard',
failureRedirect: '/login',
});
};
```
Now you are free to include social buttons on the login page however you like
```tsx
// app/routes/login.tsx
import { Form } from '@remix-run/react';
import { SocialsProvider } from 'remix-auth-socials';
interface SocialButtonProps {
provider: SocialsProvider;
label: string;
}
const SocialButton: React.FC<SocialButtonProps> = ({ provider, label }) => (
<Form action={`/auth/${provider}`} method="post">
<button>{label}</button>
</Form>
);
export default function Login() {
return (
<>
<SocialButton
provider={SocialsProvider.DISCORD}
label="Login with Discord"
/>
<SocialButton
provider={SocialsProvider.GITHUB}
label="Login with Github"
/>
<SocialButton
provider={SocialsProvider.GOOGLE}
label="Login with Google"
/>
<SocialButton
provider={SocialsProvider.FACEBOOK}
label="Login with Facebook"
/>
<SocialButton
provider={SocialsProvider.MICROSOFT}
label="Login with Microsoft"
/>
<SocialButton
provider={SocialsProvider.LINKEDIN}
label="Login with LinkedIn"
/>
</>
);
}
```
You will also need a logout route
```ts
// app/routes/logout.tsx
import { ActionArgs } from '@remix-run/node';
import { authenticator } from '~/server/auth.server';
export let action = async ({ request, params }: ActionArgs) => {
await authenticator.logout(request, { redirectTo: '/' });
};
```
### Create the strategy instance
For each social you want to use, you must initialise it in your `auth.server.ts` file.
```ts
// app/server/auth.server.ts
import { Authenticator } from 'remix-auth';
import {
GoogleStrategy,
FacebookStrategy,
SocialsProvider,
} from 'remix-auth-socials';
import { sessionStorage } from '~/services/session.server';
// Create an instance of the authenticator
export let authenticator = new Authenticator(sessionStorage, {
sessionKey: '_session',
});
// You may specify a <User> type which the strategies will return (this will be stored in the session)
// export let authenticator = new Authenticator<User>(sessionStorage, { sessionKey: '_session' });
const getCallback = (provider: SocialsProvider) => {
return `http://localhost:3333/auth/${provider}/callback`;
};
authenticator.use(
new GoogleStrategy(
{
clientID: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
callbackURL: getCallback(SocialsProvider.GOOGLE),
},
async ({ profile }) => {
// here you would find or create a user in your database
return profile;
},
),
);
authenticator.use(
new FacebookStrategy(
{
clientID: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
callbackURL: getCallback(SocialsProvider.FACEBOOK),
},
async ({ profile }) => {},
),
);
```
### Add a protected route and an automatic success redirect
Here's an example of a protected route
```tsx
// app/routes/dashboard.tsx
import { useLoaderData, Form } from '@remix-run/react';
import { LoaderArgs } from '@remix-run/node';
import { authenticator } from '~/server/auth.server';
export let loader = async ({ request, params }: LoaderArgs) => {
const user = await authenticator.isAuthenticated(request, {
failureRedirect: '/',
});
return { user };
};
export default function Dashboard() {
const { user } = useLoaderData<typeof loader>();
return (
<div>
<h1>Welcome {user.displayName}!</h1>
<p>This is a protected page</p>
<Form action="/logout" method="post">
<button>Logout</button>
</Form>
</div>
);
}
```
You might also want your index route to redirect to the dashboard for logged in users.
```tsx
// app/routes/index.tsx
import { useLoaderData } from '@remix-run/react';
import { LoaderArgs } from '@remix-run/node';
import { authenticator } from '~/server/auth.server';
export let loader = async ({ request, params }: LoaderArgs) => {
const user = await authenticator.isAuthenticated(request, {
successRedirect: '/dashboard',
});
return user;
};
export default function Index() {
return (
<div>
<h1>Welcome!</h1>
<p>
<a href="/login">Please log in</a>
</p>
</div>
);
}
```