未定义 Gridsome 服务器端渲染与窗口中断的 Auth0 身份验证

Posted

技术标签:

【中文标题】未定义 Gridsome 服务器端渲染与窗口中断的 Auth0 身份验证【英文标题】:Auth0 authentication with Gridsome server side rendering breaks with window is undefined 【发布时间】:2019-10-11 22:22:46 【问题描述】:

我已经根据他们使用 Gridsome 的教程实现了 auth0 Vuejs,它在开发中运行良好。 但是,当我运行gridsome build 时,构建失败,因为window 在服务器上下文中未定义。

我在 Auth0-js 库中发现了一些问题,声称 Auth0 只能在客户端使用,但是,由于 Gridsome 的工作方式,我似乎找不到只加载 Auth0 的方法-js 在客户端。

Gridsome 有 main.js,我将在其中添加插件,并在其中定义身份验证路由。

Main.js

import AuthServicePlugin from '~/plugins/auth0.plugin'
import auth from '~/auth/auth.service'

export default function (Vue,  router, head, isClient ) 
  ...
  Vue.use(AuthServicePlugin)
  //Handle Authentication
  router.beforeEach((to, from, next) => 
    if (to.path === "/auth/logout" || to.path === "/auth/callback" || auth.isAuthenticated()) 
      return next();
    

    // Specify the current path as the customState parameter, meaning it
    // will be returned to the application after auth
      auth.login( target: to.path );

  )

基于 Gatsbyb.js auth0 implementation tutorial,我尝试使用 null-loader 将 auth0-js 从 webpack 加载中排除

gridsome.config.js

configureWebpack: 
    /*
     * During the build step, `auth0-js` will break because it relies on
     * browser-specific APIs. Fortunately, we don’t need it during the build.
     * Using Webpack’s null loader, we’re able to effectively ignore `auth0-js`
     * during the build. (See `src/utils/auth.js` to see how we prevent this
     * from breaking the app.)
    */
    module: 
      rules: [
        
          test: /auth0-js/,
          use: 'null-loader',
        ,
      ],
    ,

我很想了解如何使用 Gridsome 仅在客户端上下文中包含和加载 Auth0

【问题讨论】:

从您的第二个代码 sn-p (See src/utils/auth.js to see how we prevent this from breaking the app.) 转到 here 并在页面上搜索 // src/utils/auth.js - 大约在页面下方的 1/4 处,他们提供了如何防止这种情况发生的代码破坏应用程序(你读过那些 cmets 吗?) 我遵循了那个确切的教程,但无法从他们的示例中获取 auth.js 与他们的 VUE 示例中的 auth.js 匹配。对于 vue,您需要创建一个 vue 插件。显然这造成了差异,因为 webpack 配置在构建时在服务器上导入了所有插件需求,并且 auth0-js 代码引用了窗口对象 运气好@Altryne?遇到同样的问题 @HelderLucas 实际上转移到了 nuxtjs 并且使用 @nuxtjs/auth 模块更简单,花了我半天时间没有问题 @Altryne 感谢您的回复。与我倾向于采取的路线完全相同 【参考方案1】:

在 Gridsome 中使用 Firebase 身份验证时遇到了同样的问题。

created() 生命周期钩子中的代码似乎在 Gridsome 构建过程(这是一个服务器环境)中执行,但 mounted() 生命周期钩子中的代码仅在浏览器中执行!

解决方案是将只应在客户端中运行的所有代码放在 mounted 生命周期挂钩中。

mounted() 
  // load the `auth0-js` here
  ...


在我的实例中(使用 Firebase 身份验证),这是解决方案:

在默认布局组件中:

const app = import("firebase/app");
    const auth = import("firebase/auth");
    const database = import("firebase/firestore");
    const storage = import("firebase/storage");

    Promise.all([app, auth, database, storage]).then(values => 
      // now we can access the loaded libraries ?!
    );


【讨论】:

以上是关于未定义 Gridsome 服务器端渲染与窗口中断的 Auth0 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

mui-datatable 服务器端渲染“WebpackError:ReferenceError:未定义窗口”

React 服务器端渲染 AJAX setState() - 未定义文档

角度SSR - ReferenceError:未定义元素

NextJS - 未定义窗口

Vue 开发实战生态篇 # 21:Nuxt解决了哪些问题?

Gatsby 构建失败 - 错误“窗口”在服务器端渲染期间不可用