Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3b544de
remix auth framework
coreyEntropy Jan 3, 2023
3863f69
Merge branch 'nextauthjs:main' into main
acoreyj Jan 3, 2023
7da71a5
Update packages/frameworks-remix/package.json
acoreyj Jan 4, 2023
cedcd7c
Merge branch 'nextauthjs:main' into main
acoreyj Jan 4, 2023
a9d48c6
Merge branch 'nextauthjs:main' into main
acoreyj Jan 10, 2023
4c07976
Merge branch 'nextauthjs:main' into main
acoreyj Jan 16, 2023
41520e3
updates
coreyEntropy Jan 16, 2023
1560af8
Merge branch 'main' of github.com:acoreyj/next-auth
coreyEntropy Jan 16, 2023
3a95d3a
updates
coreyEntropy Jan 16, 2023
fbbbfe3
wip
coreyEntropy Jan 16, 2023
1baf515
need tests next
acoreyj Jan 16, 2023
eac03f1
Merge branch 'nextauthjs:main' into main
acoreyj Jan 17, 2023
9219962
updates
coreyEntropy Jan 17, 2023
57a4d26
Merge branch 'main' of github.com:acoreyj/next-auth
coreyEntropy Jan 17, 2023
8aa88a6
params refractor
acoreyj Jan 17, 2023
c44a420
Merge branch 'main' of github.com:acoreyj/next-auth
acoreyj Jan 17, 2023
e4a106a
Waiting for remix bug fixes
coreyEntropy Jan 17, 2023
30fe74e
remove unecessary
coreyEntropy Jan 17, 2023
ee2f6ef
remix note
coreyEntropy Jan 17, 2023
09a3864
Merge branch 'main' into main
acoreyj Jan 18, 2023
04776fb
fix email creating bad url
coreyEntropy Jan 24, 2023
999b161
Merge branch 'main' of github.com:acoreyj/next-auth
coreyEntropy Jan 24, 2023
8293aae
Merge branch 'main' of github.com:acoreyj/next-auth
coreyEntropy Jan 24, 2023
115d7e5
fixes
coreyEntropy Jan 25, 2023
4d55fd9
updates
coreyEntropy Feb 18, 2023
23d9dbe
updates
coreyEntropy Feb 20, 2023
53ae974
Merge branch 'main' into remix-auth
coreyEntropy Feb 20, 2023
f9ec39f
Merge branch 'main' into remix-auth
acoreyj Sep 9, 2024
5008e6b
update remix version
acoreyj Sep 9, 2024
510098e
chore: checkpoint work in progress
acoreyj Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions packages/frameworks-remix/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
Remix Auth is a Remix integration for Auth.js.
It provides a simple way to add authentication to your Remix app in a few lines of code.

## Installation

```bash npm2yarn2pnpm
npm install @auth/core @auth/remix
```

## Configuration

In your remix.config.js we need to add the esm modules so they are properly bundled.

This will always include @auth/core, oauth4webapi, preact-render-to-string and any providers you use.

e.g

```js title="remix.config.js"

module.exports = {
...
serverDependenciesToBundle: [
"@auth/core",
"oauth4webapi",
"preact-render-to-string",
"@auth/core/providers/google",
],
};

```

## Usage

Create a .server file to create and access the authenticator

```ts title="services/auth.server.ts"
import { RemixAuthenticator } from "remix-auth/src/lib"
import Google from "@auth/core/providers/google"
import type { AppLoadContext } from "@remix-run/cloudflare"
import { D1Adapter } from "@auth/adapter-d1"

// Create an instance of the authenticator
let authenticator: RemixAuthenticator<Record<string, unknown>>

export const getAuthenticator = (env: Record<string, any> | AppLoadContext) => {
if (!authenticator) {
authenticator = new RemixAuthenticator(
{
session: {
strategy: "jwt",
},
debug: env.NODE_ENV === "development",
adapter: D1Adapter(env["vsle-keystone"] as D1Database),
providers: [
Google({
clientId: env.GOOGLE_CLIENT_ID as string,
clientSecret: env.GOOGLE_CLIENT_SECRET as string,
}) as unknown as any,
],
},
env
)
}
return authenticator
}
```

Create a route for your auth, this is most simply done using optional routes like file named `auth.$action.($providerId).tsx`

WARNING: In order to fully and securely support progressive enhancement for auth actions (automatically handling getting csrf tokens regardless of javascript) this route MUST be a [Resource Route](https://remix.run/docs/en/v1/guides/api-routes#resource-routes).

Relevant remix discussion (here)[https://github.com/remix-run/remix/discussions/5258]

```ts title="auth.$action.($providerId).tsx"
import type { ActionFunction, LoaderFunction } from "@remix-run/node"
import { getAuthenticator } from "~/services/auth.server"

export let loader: LoaderFunction = async ({ request, params, context }) => {
const result = getAuthenticator(
context.env as Record<string, string>
).handleAuthRoute({
request,
action: params.action!,
providerId: params.providerId,
params,
})
return result
}

export let action: ActionFunction = async ({ request, params, context }) => {
const result = getAuthenticator(
context.env as Record<string, string>
).handleAuthRoute({
request,
action: params.action!,
providerId: params.providerId,
params,
})
return result
}
```

Don't forget to set the `AUTH_SECRET` [environment variable](https://kit.svelte.dev/docs/modules#$env-static-private). This should be a random 32 character string. On unix systems you can use `openssl rand -hex 32` or check out `https://generate-secret.vercel.app/32`.

When deploying your app outside Vercel, set the `AUTH_TRUST_HOST` variable to `true` for other hosting providers like Cloudflare Pages or Netlify.

The callback URL used by the [providers](https://authjs.dev/reference/core/modules/providers) must be set to the following, unless you override {@link SvelteKitAuthConfig.prefix}:

```
[origin]/auth/callback/[provider]
```

## Signing in, signing out and getting the user

(and yes it takes advantage of remix's progressive enhancement and works without javascript!)

!WARN for email you will likely need to alter the route or the login page to properly handle the response from email which should give a message that an email has been sent

```ts title="index.tsx"
import { getAuthenticator } from "~/services/auth.server"
import type { DataFunctionArgs } from "@remix-run/cloudflare"
import { useRef } from "react"
import { useFetcher, useLoaderData } from "@remix-run/react"
import { SignInForm, SignOutForm } from "remix-auth/src/lib/components"
export const loader = async ({ request, context }: DataFunctionArgs) => {
const authenticator = getAuthenticator(context.env as Record<string, any>)
const providers = await authenticator.getProviders(request)
const user = await authenticator.isAuthenticated(request)
return { user, providers }
}

export default function Auth() {
const { user, providers } = useLoaderData<typeof loader>()
const fetcher = useFetcher()
const loading = fetcher.state === "loading" || fetcher.state === "submitting"
const signOutForm = useRef<HTMLFormElement>(null)
return (
<div className="">
<section className="container">
{user ? (
<div>
<h1 className="">{user.name}</h1>
<SignOutForm ref={signOutForm} fetcher={fetcher}>
<button disabled={loading} aria-busy={loading}>
Sign Out
</button>
</SignOutForm>
</div>
) : (
<>
{Object.entries(providers).map(([key, provider]) => {
return (
<SignInForm
fetcher={fetcher}
providerId={provider.id}
key={key}
>
<input
type="hidden"
name="callbackUrl"
value={
typeof document !== "undefined"
? window.location.href
: ""
}
/>
{provider.type === "email" && (
<>
<label htmlFor="email">Email address</label>
<input
type="email"
id="email"
name="email"
placeholder="Email address"
required
/>
</>
)}
<button disabled={loading} aria-busy={loading}>
Sign In with {provider.name}
</button>
</SignInForm>
)
})}
</>
)}
</section>
</div>
)
}
```

Special thanks to Sergio Xalambrí of https://github.com/sergiodxa/remix-auth / https://sergiodxa.com
61 changes: 61 additions & 0 deletions packages/frameworks-remix/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@auth/remix",
"description": "Authentication for Remix.",
"version": "0.2.0",
"license": "ISC",
"type": "module",
"files": [
"client.*",
"index.*",
"src"
],
"engines": {
"node": ">=18.17"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./client": {
"types": "./dist/client.d.ts",
"import": "./dist/client.js"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "tsup --config ./tsup.config.js",
"patch": "npm version patch --no-git-tag-version",
"clean": "rm -rf utils.* index.* types.*"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"cookie": "^0.5.0"
},
"devDependencies": {
"@auth/core": "workspace:*",
"@remix-run/react": "^2.11.2",
"@remix-run/serve": "^2.11.2",
"@types/node": "^18.7.14",
"next-auth": "workspace:*",
"react": "^18",
"react-dom": "^18",
"typescript": "^4.8.2",
"tsup": "^6.5.0",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6"
},
"keywords": [
"Remix",
"React",
"Auth"
],
"author": {
"name": "Corey Jepperson",
"email": "corey.jepperson@gmail.com",
"url": "http://corey.jepperson.us"
},
"repository": "https://github.com/nextauthjs/next-auth"
}
Loading
Loading