From c690a68b3c01fc9381057a72b35b063028f0d023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuzcan=20K=C3=B6se?= Date: Wed, 24 Jun 2020 22:53:04 +0100 Subject: [PATCH 1/2] Update index.js (#14528) * Update index.js * Update index.js * Update examples/with-firebase-authentication/pages/index.js Co-authored-by: Luis Alvarez D --- examples/with-firebase-authentication/pages/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/with-firebase-authentication/pages/index.js b/examples/with-firebase-authentication/pages/index.js index 303032df49520..d0067c0cdb218 100644 --- a/examples/with-firebase-authentication/pages/index.js +++ b/examples/with-firebase-authentication/pages/index.js @@ -15,7 +15,6 @@ const Index = () => { user ? ['/api/getFood', user.token] : null, fetcher ) - if (!user) { return ( <> @@ -52,7 +51,11 @@ const Index = () => { {error &&
Failed to fetch food!
} - {data &&
Your favorite food is {data.food}.
} + {data ? ( +
Your favorite food is {data.food}.
+ ) : ( +
Loading...
+ )} ) } From fe529c49bf2642777c6f4c24c8ea1045ed5cd339 Mon Sep 17 00:00:00 2001 From: Nico Domino Date: Thu, 25 Jun 2020 00:24:02 +0200 Subject: [PATCH 2/2] Add 'with-next-auth' example (#14530) I accidentally deleted the repo the original PR was based upon haha. Anyway, the code was still on my computer so here's a new PR with the same content. I addressed the latest comments from @lfades in the old PR (https://github.com/vercel/next.js/pull/14180) I also updated `next-auth` to `2.1.0` and updated the `` component in `_app.js` that needed updating since the latest release. Let me know if I missed anything else, otherwise I think this should be good to go :thumbsup: --- examples/with-cookie-auth/README.md | 1 + examples/with-next-auth/.env.development | 1 + examples/with-next-auth/.env.local.example | 11 ++ examples/with-next-auth/README.md | 50 +++++++++ examples/with-next-auth/components/footer.js | 17 +++ .../components/footer.module.css | 14 +++ examples/with-next-auth/components/nav.js | 61 ++++++++++ .../with-next-auth/components/nav.module.css | 79 +++++++++++++ examples/with-next-auth/package.json | 17 +++ examples/with-next-auth/pages/_app.js | 13 +++ .../pages/api/auth/[...nextauth].js | 105 ++++++++++++++++++ examples/with-next-auth/pages/index.js | 30 +++++ examples/with-next-auth/styles.css | 29 +++++ 13 files changed, 428 insertions(+) create mode 100644 examples/with-next-auth/.env.development create mode 100644 examples/with-next-auth/.env.local.example create mode 100644 examples/with-next-auth/README.md create mode 100644 examples/with-next-auth/components/footer.js create mode 100644 examples/with-next-auth/components/footer.module.css create mode 100644 examples/with-next-auth/components/nav.js create mode 100644 examples/with-next-auth/components/nav.module.css create mode 100644 examples/with-next-auth/package.json create mode 100644 examples/with-next-auth/pages/_app.js create mode 100644 examples/with-next-auth/pages/api/auth/[...nextauth].js create mode 100644 examples/with-next-auth/pages/index.js create mode 100644 examples/with-next-auth/styles.css diff --git a/examples/with-cookie-auth/README.md b/examples/with-cookie-auth/README.md index a2f9ade600899..68952f384d689 100644 --- a/examples/with-cookie-auth/README.md +++ b/examples/with-cookie-auth/README.md @@ -4,3 +4,4 @@ This example has been deprecated and removed in favor of one of the following ex - [with-cookie-auth-fauna](https://github.com/vercel/next.js/tree/canary/examples/with-cookie-auth-fauna) - [with-passport](https://github.com/vercel/next.js/tree/canary/examples/with-passport) - [with-iron-session](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) +- [with-next-auth](https://github.com/vercel/next.js/tree/canary/examples/with-next-auth) diff --git a/examples/with-next-auth/.env.development b/examples/with-next-auth/.env.development new file mode 100644 index 0000000000000..d25c047eea93a --- /dev/null +++ b/examples/with-next-auth/.env.development @@ -0,0 +1 @@ +SITE=http://localhost:3000 diff --git a/examples/with-next-auth/.env.local.example b/examples/with-next-auth/.env.local.example new file mode 100644 index 0000000000000..303e34e8c2b81 --- /dev/null +++ b/examples/with-next-auth/.env.local.example @@ -0,0 +1,11 @@ +GOOGLE_ID= +GOOGLE_SECRET= +FACEBOOK_ID= +FACEBOOK_SECRET= +TWITTER_ID= +TWITTER_SECRET= +GITHUB_ID= +GITHUB_SECRET= +EMAIL_SERVER=smtp://username:password@smtp.example.com.com:587 +EMAIL_FROM=NextAuth +DATABASE_URL=sqlite://localhost/:memory:?synchronize=true diff --git a/examples/with-next-auth/README.md b/examples/with-next-auth/README.md new file mode 100644 index 0000000000000..ecbd6f9013f6b --- /dev/null +++ b/examples/with-next-auth/README.md @@ -0,0 +1,50 @@ +# NextAuth.js Example + +Next.js example with [`next-auth`](https://github.com/iaincollins/next-auth), an open source, easy to use, and secure by default authentication library. + +## How to use + +Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git): + +```bash +cp .env.local.example .env.local +``` + +Then, you'll need to fill at least one of the authentication providers by adding the required secrets for it, be that in the form of OAuth keys/secrets from a provider (Google, Twitter, etc.) or an SMTP connection string to enable email authentication. + +More details about the providers can be found [here](https://next-auth.js.org/configuration/providers), and for a more complete introduction to `next-auth` check out their [introduction guide](https://next-auth.js.org/getting-started/introduction) + +It is vital that you know the deployment URL and define it in the environment file. + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example next-auth with-next-auth-app +# or +yarn create next-app --example next-auth with-next-auth-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/next-auth +cd next-auth +``` + +Install it and run: + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +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)). + +**Note:** For production you need to know in advance the domain (deployment URL) of your application, as it would be required for OAuth to work, once you have it set it to the `VERCEL_URL` environment variable under the settings of your Vercel project. diff --git a/examples/with-next-auth/components/footer.js b/examples/with-next-auth/components/footer.js new file mode 100644 index 0000000000000..991b6045f1bb9 --- /dev/null +++ b/examples/with-next-auth/components/footer.js @@ -0,0 +1,17 @@ +import styles from './footer.module.css' + +const Footer = () => ( +
+
+ +
+) + +export default Footer diff --git a/examples/with-next-auth/components/footer.module.css b/examples/with-next-auth/components/footer.module.css new file mode 100644 index 0000000000000..e97fe32cbc927 --- /dev/null +++ b/examples/with-next-auth/components/footer.module.css @@ -0,0 +1,14 @@ +.footer { + margin-top: 2rem; +} + +.navigation { + margin-bottom: 2rem; + padding: 0; + list-style: none; +} + +.navigationItem { + display: inline-block; + margin-right: 1rem; +} diff --git a/examples/with-next-auth/components/nav.js b/examples/with-next-auth/components/nav.js new file mode 100644 index 0000000000000..b231cb36f67f8 --- /dev/null +++ b/examples/with-next-auth/components/nav.js @@ -0,0 +1,61 @@ +import { signin, signout, useSession } from 'next-auth/client' +import styles from './nav.module.css' + +/** + * The approach used in this component shows how to built a sign in and sign out + * component that works on pages which support both client and server side + * rendering, and avoids any flash incorrect content on initial page load. + **/ +const Nav = () => { + const [session, loading] = useSession() + + return ( + + ) +} + +export default Nav diff --git a/examples/with-next-auth/components/nav.module.css b/examples/with-next-auth/components/nav.module.css new file mode 100644 index 0000000000000..10d41f1401f25 --- /dev/null +++ b/examples/with-next-auth/components/nav.module.css @@ -0,0 +1,79 @@ +.loading, +.loaded { + position: relative; + top: 0; + opacity: 1; + overflow: auto; + border-radius: 0 0 0.6rem 0.6rem; + padding: 0.4rem 0.8rem; + margin: 0; + background-color: #f5f5f5; + transition: all 0.2s ease-in-out; +} + +.loading { + top: -2rem; + opacity: 0; +} + +.signedIn, +.notSignedIn { + position: absolute; + padding: 0.6rem 0 0.4rem 0; + left: 1rem; + right: 7rem; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: inherit; + z-index: 1; +} + +.signedIn { + left: 3.8rem; +} + +.avatar { + border-radius: 2rem; + float: left; + height: 2.2rem; + width: 2.2rem; + background-color: white; + background-size: cover; + border: 2px solid #ddd; +} + +.signinButton, +.signoutButton { + float: right; + margin-right: -0.4rem; + font-weight: 500; + background-color: #1eb1fc; + color: #fff; + border: 1px solid #1eb1fc; + border-radius: 2rem; + cursor: pointer; + font-size: 1rem; + line-height: 1rem; + padding: 0.5rem 1rem; + position: relative; + z-index: 10; +} + +.signinButton:hover { + background-color: #1b9fe2; + border-color: #1b9fe2; + color: #fff; +} + +.signoutButton { + background-color: #fff; + border-color: #bbb; + color: #555; +} + +.signoutButton:hover { + background-color: #fff; + border-color: #aaa; + color: #333; +} diff --git a/examples/with-next-auth/package.json b/examples/with-next-auth/package.json new file mode 100644 index 0000000000000..8648b31f28827 --- /dev/null +++ b/examples/with-next-auth/package.json @@ -0,0 +1,17 @@ +{ + "name": "next-auth-example", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "license": "ISC", + "dependencies": { + "next": "latest", + "next-auth": "^2.1.0", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "sqlite3": "^4.2.0" + } +} diff --git a/examples/with-next-auth/pages/_app.js b/examples/with-next-auth/pages/_app.js new file mode 100644 index 0000000000000..8f9fd80ebc587 --- /dev/null +++ b/examples/with-next-auth/pages/_app.js @@ -0,0 +1,13 @@ +import { Provider } from 'next-auth/client' +import '../styles.css' + +const App = ({ Component, pageProps }) => { + const { session } = pageProps + return ( + + + + ) +} + +export default App diff --git a/examples/with-next-auth/pages/api/auth/[...nextauth].js b/examples/with-next-auth/pages/api/auth/[...nextauth].js new file mode 100644 index 0000000000000..c76795480ce0b --- /dev/null +++ b/examples/with-next-auth/pages/api/auth/[...nextauth].js @@ -0,0 +1,105 @@ +import NextAuth from 'next-auth' +import Providers from 'next-auth/providers' + +const options = { + site: process.env.VERCEL_URL, + providers: [ + Providers.Email({ + // SMTP connection string or nodemailer configuration object https://nodemailer.com/ + server: process.env.EMAIL_SERVER, + // Email services often only allow sending email from a valid/verified address + from: process.env.EMAIL_FROM, + }), + // When configuring oAuth providers make sure you enabling requesting + // permission to get the users email address (required to sign in) + Providers.Google({ + clientId: process.env.GOOGLE_ID, + clientSecret: process.env.GOOGLE_SECRET, + }), + Providers.Facebook({ + clientId: process.env.FACEBOOK_ID, + clientSecret: process.env.FACEBOOK_SECRET, + }), + Providers.Twitter({ + clientId: process.env.TWITTER_ID, + clientSecret: process.env.TWITTER_SECRET, + }), + Providers.GitHub({ + clientId: process.env.GITHUB_ID, + clientSecret: process.env.GITHUB_SECRET, + }), + ], + // The 'database' option should be a connection string or TypeORM + // configuration object https://typeorm.io/#/connection-options + // + // Notes: + // * You need to install an appropriate node_module for your database! + // * The email sign in provider requires a database but OAuth providers do not + database: process.env.DATABASE_URL, + + session: { + // Use JSON Web Tokens for session instead of database sessions. + // This option can be used with or without a database for users/accounts. + // Note: `jwt` is automatically set to `true` if no database is specified. + // jwt: false, + // Seconds - How long until an idle session expires and is no longer valid. + // maxAge: 30 * 24 * 60 * 60, // 30 days + // Seconds - Throttle how frequently to write to database to extend a session. + // Use it to limit write operations. Set to 0 to always update the database. + // Note: This option is ignored if using JSON Web Tokens + // updateAge: 24 * 60 * 60, // 24 hours + // Easily add custom properties to response from `/api/auth/session`. + // Note: This should not return any sensitive information. + /* + get: async (session) => { + session.customSessionProperty = "ABC123" + return session + } + */ + }, + + // JSON Web Token options + jwt: { + // secret: 'my-secret-123', // Recommended (but auto-generated if not specified) + // Custom encode/decode functions for signing + encryption can be specified. + // if you want to override what is in the JWT or how it is signed. + // encode: async ({ secret, key, token, maxAge }) => {}, + // decode: async ({ secret, key, token, maxAge }) => {}, + // Easily add custom to the JWT. It is updated every time it is accessed. + // This is encrypted and signed by default and may contain sensitive information + // as long as a reasonable secret is defined. + /* + set: async (token) => { + token.customJwtProperty = "ABC123" + return token + } + */ + }, + + // Control which users / accounts can sign in + // You can use this option in conjuction with OAuth and JWT to control which + // accounts can sign in without having to use a database. + allowSignin: async (user, account) => { + // Return true if user / account is allowed to sign in. + // Return false to display an access denied message. + return true + }, + + // You can define custom pages to override the built-in pages + // The routes shown here are the default URLs that will be used. + pages: { + // signin: '/api/auth/signin', // Displays signin buttons + // signout: '/api/auth/signout', // Displays form with sign out button + // error: '/api/auth/error', // Error code passed in query string as ?error= + // verifyRequest: '/api/auth/verify-request', // Used for check email page + // newUser: null // If set, new users will be directed here on first sign in + }, + + // Additional options + // secret: 'abcdef123456789' // Recommended (but auto-generated if not specified) + // debug: true, // Use this option to enable debug messages in the console +} + +const Auth = (req, res) => NextAuth(req, res, options) + +export default Auth diff --git a/examples/with-next-auth/pages/index.js b/examples/with-next-auth/pages/index.js new file mode 100644 index 0000000000000..818c27551cd6b --- /dev/null +++ b/examples/with-next-auth/pages/index.js @@ -0,0 +1,30 @@ +import Nav from '../components/nav' +import Footer from '../components/footer' + +const NextAuth = () => ( + <> +