Skip to content

Commit

Permalink
add mvp auth
Browse files Browse the repository at this point in the history
  • Loading branch information
chantastic committed Jul 9, 2024
1 parent f9f2a0d commit cc3e363
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 0 deletions.
3 changes: 3 additions & 0 deletions chan.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
"@astrojs/react": "^3.6.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@workos-inc/node": "^7.12.0",
"iron-session": "^8.0.2",
"jose": "^5.6.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sharp": "0.33.4"
Expand Down
47 changes: 47 additions & 0 deletions chan.dev/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

178 changes: 178 additions & 0 deletions chan.dev/src/content/posts/authkit-astro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
title: AuthKit withAstro
date: 2024-07-08
references:
- https://workos.com/docs/user-management/1-configure-your-project/configure-a-redirect-uri
---

## install `@workos-inc/node`

## add secrets

- `WORKOS_API_KEY` to `.env`(.local)
- `WORKOS_CLIENT_ID` to `.env`(.local)
- (will also need to add to hosting provider)

## add redirect endpoint.

```js
export async function GET({params, redirect}) {
return redirect('https://workos.com', 302)
}
```

## return the url (not working yet)

```js
import {WorkOS} from '@workos-inc/node'
// import type {APIRoute} from 'astro'

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const client_id = import.meta.env.WORKOS_CLIENT_ID

export async function GET({params, redirect}) {
const authorizationUrl =
workos.userManagement.getAuthorizationUrl({
provider: 'authkit',
redirectUri: import.meta.env.WORKOS_REDIRECT_URI,
clientId: client_id,
})

return new Response(authorizationUrl)
// return redirect(authorizationUrl, 302)
}
```
## redirect to url
```diff
- return new Response(authorizationUrl)
+ return redirect(authorizationUrl, 302)
```
## create callback endpoint
create dynamic route that recieve authentication token
```js
import {WorkOS} from '@workos-inc/node'

export const prerender = false

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const clientId = import.meta.env.WORKOS_CLIENT_ID

export async function GET({params, request}) {
const code = new URL(request.url).searchParams.get('code')

return new Response(code)
}
```
## exchange code for user object
```js
import {WorkOS} from '@workos-inc/node'

export const prerender = false

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const clientId = import.meta.env.WORKOS_CLIENT_ID

export async function GET({request, redirect}) {
const code = new URL(request.url).searchParams
.get('code')
?.toString()

const {user} =
await workos.userManagement.authenticateWithCode({
code,
clientId,
})

console.log(user)

return new Response(JSON.stringify(user))
// return redirect('/')
}
```
## encrypt session and set cookie
```js
import {WorkOS} from '@workos-inc/node'
import {sealData /_, unsealData_/} from 'iron-session'

export const prerender = false

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const clientId = import.meta.env.WORKOS_CLIENT_ID

export async function GET({request, redirect, cookies}) {
const code = new URL(request.url).searchParams
.get('code')
?.toString()

const {user, accessToken, refreshToken, impersonator} =
await workos.userManagement.authenticateWithCode({
code,
clientId,
})

const encryptedSession = await sealData(
{accessToken, refreshToken, user, impersonator},
{password: import.meta.env.WORKOS_COOKIE_PASSWORD}
)

cookies.set('wos-session', encryptedSession, {
path: '/',
httpOnly: true,
secure: true,
sameSite: 'lax',
})

return redirect('/user')

}
```
## Read session in single view
```astro
---
import {unsealData} from 'iron-session'

export const prerender = false

const cookie = Astro.cookies.get('wos-session')

if (!cookie) {
return Astro.redirect('/auth')
}

const session = await unsealData(cookie.value, {
password: import.meta.env.WORKOS_COOKIE_PASSWORD,
})
---

<pre><code>{JSON.stringify(session, null, '\t')}</code></pre>
```
## verify session in single view
```js
const JWKS = createRemoteJWKSet(
new URL(
workos.userManagement.getJwksUrl(
import.meta.env.WORKOS_CLIENT_ID
)
)
)

try {
await jwtVerify(session.accessToken, JWKS)
} catch (e) {
console.warn('Failed to verify session:', e)
return Astro.redirect('/auth')
}
```
33 changes: 33 additions & 0 deletions chan.dev/src/pages/auth/callback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {WorkOS} from '@workos-inc/node'
import {sealData /*, unsealData*/} from 'iron-session'

export const prerender = false

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const clientId = import.meta.env.WORKOS_CLIENT_ID

export async function GET({request, redirect, cookies}) {
const code = new URL(request.url).searchParams
.get('code')
?.toString()

const {user, accessToken, refreshToken, impersonator} =
await workos.userManagement.authenticateWithCode({
code,
clientId,
})

const encryptedSession = await sealData(
{accessToken, refreshToken, user, impersonator},
{password: import.meta.env.WORKOS_COOKIE_PASSWORD}
)

cookies.set('wos-session', encryptedSession, {
path: '/',
httpOnly: true,
secure: true,
sameSite: 'lax',
})

return redirect('/user')
}
17 changes: 17 additions & 0 deletions chan.dev/src/pages/auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {WorkOS} from '@workos-inc/node'
// import type {APIRoute} from 'astro'
// export const prerender = false

const workos = new WorkOS(import.meta.env.WORKOS_API_KEY)
const clientId = import.meta.env.WORKOS_CLIENT_ID

export async function GET({redirect}) {
const authorizationUrl =
workos.userManagement.getAuthorizationUrl({
provider: 'authkit',
redirectUri: import.meta.env.WORKOS_REDIRECT_URI,
clientId,
})

return redirect(authorizationUrl, 302)
}
Loading

0 comments on commit cc3e363

Please sign in to comment.