LoginSignup
19
2

More than 3 years have passed since last update.

nextjs-auth0をdocker上でも使いたい

Last updated at Posted at 2020-11-30

nextjsでも簡単にauth0を使いたい!
と思ってサンプルに従うと、Dockerビルドってかproduction buildするとエラーで落ちちゃいます。

configのサンプル
auth0/nextjs-auth0: Next.js SDK for signing in with Auth0 (Experimental) - https://github.com/auth0/nextjs-auth0#runtime-configuration

import { initAuth0 } from '@auth0/nextjs-auth0';
import config from './config';

export default initAuth0({
  domain: process.env.AUTHO_DOMAIN,
  clientId: process.env.AUTHO_DOMAIN,
  clientSecret: process.env.APP_SECRRET,
  scope: 'openid profile',

エラー内容こんな感じ。process.env.XXXが見れないから落ちてるのかな。

Automatically optimizing pages...
> Build error occurred
Error: A valid Auth0 Domain must be provided
    at Object.createInstance [as default] (/usr/src/app/node_modules/@auth0/nextjs-auth0/dist/instance.node.js:10:15)
    at initAuth0 (/usr/src/app/node_modules/@auth0/nextjs-auth0/dist/index.js:8:46)
    at Object.xMDF (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:781:127)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at Module.1TCz (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:147:13)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at Object.0 (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:99:18)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at /usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:91:18
    at Object.<anonymous> (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:94:10)
error Command failed with exit code 1

ボツ案

issue投げて聞いてみたら、 .env を仮データで追加し実行時に再ビルドすると大丈夫らしい。試したらできた。

Can't build on docker. · Issue #86 · auth0/nextjs-auth0 - https://github.com/auth0/nextjs-auth0/issues/86

Dockerfile
FROM node:14 as builder

WORKDIR /app

COPY .env.template .env
COPY package.json yarn.lock ./
RUN yarn install

COPY . .
RUN yarn build

# ------------------
FROM node:14-alpine as release

WORKDIR /app

COPY --from=builder /app/package.json /app/yarn.lock ./
RUN yarn install
COPY --from=builder /app/.next ./.next
COPY . .

EXPOSE 3000
CMD ["yarn", "start:build"]

package.json
  "scripts": {
    "start": "next start",
    "start:build": "yarn build && yarn start",
    "build": "next build",

確かにできるんだけど、CI時にビルド2回ぐらい回しちゃうことになって、めっちゃ時間かかる・・・

改善案

initAuth0のオブジェクトを直接export defaultすると、環境変数がバインドされちゃうので、関数にしてあとからprocess.envを評価すればいいじゃんって案

Document best practices for using nextjs-auth0 with a nextjs production build. · Issue #154 · auth0/nextjs-auth0 - https://github.com/auth0/nextjs-auth0/issues/154

環境変数はgetConfig()経由で受け取り、バインドすると想定通り動いてくれた。やったね!

src/lib/auth0.js
import getConfig from 'next/config';
import { initAuth0 } from '@auth0/nextjs-auth0';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

let auth0 = null;

const proc = () => {
  if (!auth0) {
    auth0 = initAuth0({
      clientId: publicRuntimeConfig.auth0.clientId,
      domain: publicRuntimeConfig.auth0.domain,
      scope: 'openid email profile',
      postLogoutRedirectUri: publicRuntimeConfig.baseUrl,
      redirectUri: `${publicRuntimeConfig.baseUrl}/api/auth/signed-in`,
      clientSecret: serverRuntimeConfig?.auth0?.secret ?? '',
      session: {
        cookieSecret: serverRuntimeConfig?.appSecret ?? '',
        // Set to 8 hours
        cookieLifetime: 60 * 60 * 8,
        storeIdToken: false,
        storeAccessToken: false,
        storeRefreshToken: false,
      },
      oidcClient: {
        // Optionally configure the timeout in milliseconds for HTTP requests to Auth0.
        httpTimeout: 2500,
        // Optionally configure the clock tolerance in milliseconds, if the time on your server is running behind.
        clockTolerance: 10000,
      },
    });
  }

  return auth0;
};

export default proc;
next.config.js
const nextConfig = {
  serverRuntimeConfig: {
    appSecret: process.env.APP_SECRET,
    auth0: {
      secret: process.env.AUTH0_CLIENT_SECRET,
    },
  },
  publicRuntimeConfig: {
    baseUrl: process.env.NEXT_PUBLIC_BASE_URL,
    auth0: {
      clientId: process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID,
      domain: process.env.NEXT_PUBLIC_AUTH0_DOMAIN,
    },
  },
};

module.exports = nextConfig;
page/auth/api/sign-in.js
diff --git a/pages/api/auth/sign-in.js b/pages/api/auth/sign-in.js
index 7b109a7..d271932 100644
--- a/pages/api/auth/sign-in.js
+++ b/pages/api/auth/sign-in.js
@@ -1,6 +1,8 @@
-import auth0 from '../../../src/lib/auth0';
+import Auth0 from '../../../src/lib/auth0';
 import { checkHeaders } from '../../../src/lib/middleware/auth';

+const auth0 = Auth0();
+
 const login = checkHeaders(async (req, res) => {
   try {
     await auth0.handleLogin(req, res);

19
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
2