Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Examples] Remove getInitialProps from with-cookie-auth-fauna #13887

Merged
merged 13 commits into from
Jun 20, 2020
1 change: 0 additions & 1 deletion examples/with-cookie-auth-fauna/.env

This file was deleted.

1 change: 1 addition & 0 deletions examples/with-cookie-auth-fauna/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FAUNA_SERVER_KEY="<YOUR SECRET KEY GOES HERE>"
31 changes: 21 additions & 10 deletions examples/with-cookie-auth-fauna/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ In this example, we authenticate users and store a token in a secure (non-JS) co

This example uses [Fauna](https://fauna.com/) as the auth service and DB.

The repo includes a minimal auth backend built with the new [API Routes support](https://github.com/vercel/next.js/pull/7296) (`pages/api`), [Micro](https://www.npmjs.com/package/micro), [Fauna for Auth](https://app.fauna.com/tutorials/authentication) and [dotenv](https://github.com/vercel/next.js/tree/canary/examples/with-dotenv) for environment variables. The backend allows the user to create an account (a User document), login, and see their user id (User ref id).
The repo includes a minimal auth backend built with [API Routes](https://nextjs.org/docs/api-routes/introduction) and [Fauna for Auth](https://app.fauna.com/tutorials/authentication). The backend allows the user to create an account (a User document), login, and see their user id (User ref id).

Session is synchronized across tabs. If you logout your session gets removed on all the windows as well. We use the HOC `withAuthSync` for this.

Expand Down Expand Up @@ -38,11 +38,16 @@ First, you'll need to create an account on [Fauna](https://fauna.com/), then fol
1. In the [FaunaDB Console](https://dashboard.fauna.com/), click "New Database". Name it whatever you like and click "Save".
2. Click "New Collection", name it `User`, leave "Create collection index" checked, and click "Save".
3. Now go to "Indexes" in the left sidebar, and click "New Index". Select the `User` collection, call it `users_by_email`, and in the "terms" field type `data.email`. Select the "Unique" checkbox and click "Save". This will create an index that allows looking up users by their email, which we will use to log a user in.
4. Next, go to "Security" in the sidebar, then click "New Key". Create a new key with the `Server` role, call it `server-key`, and click "Save". Your key's secret will be displayed, copy that value and paste it as the value for `FAUNA_SERVER_KEY` in the `.env` file at the project root. Keep this key safely as it has privileged access to your database.
4. Next, go to "Security" in the sidebar, then click "New Key". Create a new key with the `Server` role, call it `server-key`, and click "Save". Your key's secret will be displayed, copy that value.
5. Create the `.env.local` file (which will be ignored by Git) based on the `.env.local.example` file in this directory:

> For more information, read the [User Authentication Tutorial in Fauna](https://app.fauna.com/tutorials/authentication).
```bash
cp .env.local.example .env.local
```

> **Add `.env` to `.gitignore`**, files with secrets should never be in the cloud, we have it here for the sake of the example.
6. Paste the secret you copied as the value for `FAUNA_SERVER_KEY` in the `.env.local` file. Keep this key safely as it has privileged access to your database.

> For more information, read the [User Authentication Tutorial in Fauna](https://app.fauna.com/tutorials/authentication).

Now, install it and run:

Expand All @@ -54,12 +59,18 @@ yarn
yarn dev
```

### Deploy
### Deploy on Vercel

We'll use [now](https://vercel.com/now) to deploy our app, first we need to add the server key as a secret using [now secrets](https://vercel.com/docs/v2/serverless-functions/env-and-secrets/?query=secrets#adding-secrets), like so:
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).

```bash
now secrets add fauna-secret-key "ENTER YOUR FAUNA SERVER KEY"
```
#### Deploy Your Local Project

To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/import/git?utm_source=github&utm_medium=readme&utm_campaign=next-example).

**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.

#### Deploy from Our Template

Alternatively, you can deploy using our template by clicking on the Deploy button below.

Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/select-scope?c=1&s=https://github.com/vercel/next.js/tree/canary/examples/with-cookie-auth-fauna&id=70107786&env=FAUNA_SERVER_KEY&envDescription=API%20Keys%20required%20by%20Fauna%20CMS&envLink=https://github.com/vercel/next.js/tree/canary/examples/with-cookie-auth-fauna%23run-locally)
8 changes: 0 additions & 8 deletions examples/with-cookie-auth-fauna/next.config.js

This file was deleted.

7 changes: 3 additions & 4 deletions examples/with-cookie-auth-fauna/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
},
"dependencies": {
"cookie": "^0.4.0",
"dotenv": "8.2.0",
"faunadb": "2.10.0",
"js-cookie": "^2.2.0",
"next": "^9.0.1",
"next": "^latest",
"react": "^16.8.6",
"react-dom": "^16.8.6"
"react-dom": "^16.8.6",
"swr": "0.2.3"
}
}
66 changes: 26 additions & 40 deletions examples/with-cookie-auth-fauna/pages/profile.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import cookie from 'cookie'
import Router from 'next/router'
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import useSWR from 'swr'
import { withAuthSync } from '../utils/auth'
import { FAUNA_SECRET_COOKIE } from '../utils/fauna-auth'
import { profileApi } from './api/profile'
import Layout from '../components/layout'

const Profile = (props) => {
const { userId } = props
const fetcher = (url) =>
fetch(url).then((res) => {
if (res.status >= 300) {
throw new Error('API Client error')
}

return res.json()
})

const Profile = () => {
const router = useRouter()
const { data: user, error } = useSWR('/api/profile', fetcher)

useEffect(() => {
if (error) router.push('/')
}, [error, router])

return (
<Layout>
<h1>Your user id is {userId}</h1>

{error ? (
<h1>An error has ocurred: {error.message}</h1>
) : user ? (
<h1>Your user id is {user.userId}</h1>
) : (
<h1>Loading...</h1>
)}
<style jsx>{`
h1 {
margin-bottom: 0;
Expand All @@ -21,36 +39,4 @@ const Profile = (props) => {
)
}

export async function getServerSideProps(ctx) {
if (typeof window === 'undefined') {
const { req, res } = ctx
const cookies = cookie.parse(req.headers.cookie ?? '')
const faunaSecret = cookies[FAUNA_SECRET_COOKIE]

if (!faunaSecret) {
res.writeHead(302, { Location: '/login' })
res.end()
return {}
}

const profileInfo = await profileApi(faunaSecret)

return { props: { userId: profileInfo } }
}

const response = await fetch('/api/profile')

if (response.status === 401) {
Router.push('/login')
return {}
}
if (response.status !== 200) {
throw new Error(await response.text())
}

const data = await response.json()

return { props: { userId: data.userId } }
}

export default withAuthSync(Profile)
4 changes: 0 additions & 4 deletions examples/with-cookie-auth-fauna/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,5 @@ export const withAuthSync = (Component) => {
return <Component {...props} />
}

if (Component.getServerSideProps) {
Wrapper.getServerSideProps = Component.getServerSideProps
}

return Wrapper
}