Skip to content

Commit 47d5c5a

Browse files
author
Paul Asjes
committed
Initial commit
0 parents  commit 47d5c5a

21 files changed

+5151
-0
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.eslintrc.cjs

.eslintrc.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
root: true,
3+
extends: [
4+
'eslint:recommended',
5+
'prettier',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:require-extensions/recommended',
8+
],
9+
plugins: ['require-extensions'],
10+
};

.github/workflows/release.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Release
2+
3+
on:
4+
# Support manually pushing a new release
5+
workflow_dispatch: {}
6+
# Trigger when a release is published
7+
release:
8+
types: [published]
9+
10+
defaults:
11+
run:
12+
shell: bash
13+
14+
jobs:
15+
test:
16+
name: Publish to NPM
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: 18
23+
registry-url: 'https://registry.npmjs.org'
24+
25+
- name: Install Dependencies
26+
run: |
27+
npm install
28+
29+
- name: Build project
30+
run: |
31+
npm run build
32+
33+
- name: Push Release
34+
if: ${{ !github.event.release.prerelease }}
35+
env:
36+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
37+
run: |
38+
npm publish --tag latest --access=public
39+
40+
- name: Push Pre-Release
41+
if: ${{ github.event.release.prerelease }}
42+
env:
43+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
44+
run: |
45+
npm publish --tag next --access=public

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.DS_Store
2+
node_modules
3+
dist

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"quoteProps": "consistent",
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"printWidth": 120
6+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 WorkOS
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# AuthKit Remix Library
2+
3+
The AuthKit library for Next.js provides convenient helpers for authentication and session management using WorkOS & AuthKit with Next.js.
4+
5+
## Installation
6+
7+
Install the package with:
8+
9+
```
10+
npm i @workos-inc/authkit-nextjs
11+
```
12+
13+
or
14+
15+
```
16+
yarn add @workos-inc/authkit-nextjs
17+
```
18+
19+
## Pre-flight
20+
21+
Make sure the following values are present in your `.env.local` environment variables file. The client ID and API key can be found in the [WorkOS dashboard](https://dashboard.workos.com), and the redirect URI can also be configured there.
22+
23+
```sh
24+
WORKOS_CLIENT_ID="client_..." # retrieved from the WorkOS dashboard
25+
WORKOS_API_KEY="sk_test_..." # retrieved from the WorkOS dashboard
26+
WORKOS_REDIRECT_URI="http://localhost:3000/callback" # configured in the WorkOS dashboard
27+
WORKOS_COOKIE_PASSWORD="<your password>" # generate a secure password here
28+
```
29+
30+
`WORKOS_COOKIE_PASSWORD` is the private key used to encrypt the session cookie. It has to be at least 32 characters long. You can use the [1Password generator](https://1password.com/password-generator/) or the `openssl` library to generate a strong password via the command line:
31+
32+
```
33+
openssl rand -base64 24
34+
```
35+
36+
To use the `signOut` method, you'll need to set your app's homepage in your WorkOS dashboard settings under "Redirects".
37+
38+
### Optional configuration
39+
40+
Certain environment variables are optional and can be used to debug or configure cookie settings.
41+
42+
```sh
43+
WORKOS_COOKIE_MAX_AGE='600' # maximum age of the cookie in seconds. Defaults to 31 days
44+
WORKOS_API_HOSTNAME='api.workos.com' # base WorkOS API URL
45+
WORKOS_API_HTTPS=true # whether to use HTTPS in API calls
46+
WORKOS_API_PORT=3000 # port to use for API calls
47+
```
48+
49+
## Setup
50+
51+
### Callback route
52+
53+
WorkOS requires that you have a callback URL to redirect users back to after they've authenticated. In your Next.js app, [expose an API route](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) and add the following.
54+
55+
```ts
56+
import { handleAuth } from '@workos-inc/authkit-nextjs';
57+
58+
export const GET = handleAuth();
59+
```
60+
61+
Make sure this route matches the `WORKOS_REDIRECT_URI` variable and the configured redirect URI in your WorkOS dashboard. For instance if your redirect URI is `http://localhost:3000/auth/callback` then you'd put the above code in `/app/auth/callback/route.ts`.
62+
63+
You can also control the pathname the user will be sent to after signing-in by passing a `returnPathname` option to `handleAuth` like so:
64+
65+
```ts
66+
export const GET = handleAuth({ returnPathname: '/dashboard' });
67+
```
68+
69+
### Middleware
70+
71+
This library relies on [Next.js middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) to provide session management for routes. Put the following in your `middleware.ts` file in the root of your project:
72+
73+
```ts
74+
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
75+
76+
export default authkitMiddleware();
77+
78+
// Match against pages that require auth
79+
// Leave this out if you want auth on every resource (including images, css etc.)
80+
export const config = { matcher: ['/', '/admin'] };
81+
```
82+
83+
## Usage
84+
85+
### Get the current user
86+
87+
For pages where you want to display a signed-in and signed-out view, use `getUser` to retrieve the user profile from WorkOS.
88+
89+
```jsx
90+
import Link from 'next/link';
91+
import { getSignInUrl, getSignUpUrl, getUser, signOut } from '@workos-inc/authkit-nextjs';
92+
93+
export default async function HomePage() {
94+
// Retrieves the user from the session or returns `null` if no user is signed in
95+
const { user } = await getUser();
96+
97+
if (!user) {
98+
// Get the URL to redirect the user to AuthKit to sign in
99+
const signInUrl = await getSignInUrl();
100+
101+
// Get the URL to redirect the user to AuthKit to sign up
102+
const signUpUrl = await getSignUpUrl();
103+
104+
return (
105+
<>
106+
<Link href={signInUrl}>Log in</Link>
107+
<Link href={signUpUrl}>Sign Up</Link>
108+
</>
109+
);
110+
}
111+
112+
return (
113+
<form
114+
action={async () => {
115+
'use server';
116+
await signOut();
117+
}}
118+
>
119+
<p>Welcome back {user?.firstName && `, ${user?.firstName}`}</p>
120+
<button type="submit">Sign out</button>
121+
</form>
122+
);
123+
}
124+
```
125+
126+
### Requiring auth
127+
128+
For pages where a signed-in user is mandatory, you can use the `ensureSignedIn` option:
129+
130+
```jsx
131+
const { user } = await getUser({ ensureSignedIn: true });
132+
```
133+
134+
Enabling `ensureSignedIn` will redirect users to AuthKit if they attempt to access the page without being authenticated.
135+
136+
### Middleware auth
137+
138+
The default behavior of this library is to request authentication via the `getUser` method on a per-page basis. There are some use cases where you don't want to call `getUser` (e.g. you don't need user data for your page) or if you'd prefer a "secure by default" approach where every route defined in your middleware matcher is protected unless specified otherwise. In those cases you can opt-in to use middleware auth instead:
139+
140+
```ts
141+
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
142+
143+
export default authkitMiddleware({
144+
middlewareAuth: {
145+
enabled: true,
146+
unauthenticatedPaths: ['/', '/about'],
147+
},
148+
});
149+
150+
// Match against pages that require auth
151+
// Leave this out if you want auth on every resource (including images, css etc.)
152+
export const config = { matcher: ['/', '/admin/:path*', '/about'] };
153+
```
154+
155+
In the above example the `/admin` page will require a user to be signed in, whereas `/` and `/about` can be accessed without signing in.
156+
157+
`unauthenticatedPaths` uses the same glob logic as the [Next.js matcher](https://nextjs.org/docs/pages/building-your-application/routing/middleware#matcher).
158+
159+
### Signing out
160+
161+
Use the `signOut` method to sign out the current logged in user and redirect to your app's homepage. The homepage redirect is set in your WorkOS dashboard settings under "Redirect".
162+
163+
### Visualizing an impersonation
164+
165+
Render the `Impersonation` component in your app so that it is clear when someone is [impersonating a user](https://workos.com/docs/user-management/impersonation).
166+
The component will display a frame with some information about the impersonated user, as well as a button to stop impersonating.
167+
168+
```jsx
169+
import { Impersonation } from '@workos-inc/authkit-nextjs';
170+
171+
export default function App() {
172+
return (
173+
<div>
174+
<Impersonation />
175+
{/* Your app content */}
176+
</div>
177+
);
178+
}
179+
```
180+
181+
### Get the access token
182+
183+
Sometimes it is useful to obtain the access token directly, for instance to make API requests to another service.
184+
185+
```jsx
186+
import { getUser } from '@workos-inc/authkit-nextjs';
187+
188+
export default async function HomePage() {
189+
const { accessToken } = await getUser();
190+
191+
if (!accessToken) {
192+
return <div>Not signed in</div>;
193+
}
194+
195+
const serviceData = await fetch('/api/path', {
196+
headers: {
197+
Authorization: `Bearer ${accessToken}`,
198+
},
199+
});
200+
201+
return <div>{serviceData}</div>;
202+
}
203+
```
204+
205+
### Debugging
206+
207+
To enable debug logs, initialize the middleware with the debug flag enabled.
208+
209+
```js
210+
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
211+
212+
export default authkitMiddleware({ debug: true });
213+
```
214+
215+
### Troubleshooting
216+
217+
#### NEXT_REDIRECT error when using try/catch blocks
218+
219+
Wrapping a `getUser({ ensureSignedIn: true })` call in a try/catch block will cause a `NEXT_REDIRECT` error. This is because `getUser` will attempt to redirect the user to AuthKit if no session is detected and redirects in Next must be [called outside a try/catch](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting).

authkit-remix-0.1.0.tgz

14.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)