首页 > 解决方案 > Auth0 SPA TypeError:无法读取未定义的属性“idTokenPayload”

问题描述

尝试登录时,我的 Gatsby+Auth0 应用程序出现错误。这是错误:

TypeError: Cannot read property 'idTokenPayload' of undefined
(anonymous function)
src/utils/auth.js:1
> 1 | import auth0 from "auth0-js"
  2 | import { navigate } from "gatsby"
  3 | 
  4 | const isBrowser = typeof window !== "undefined"

当我登录到我的应用程序时,它第一次工作,我可以看到 authResult 是控制台记录正确的值,但是当我单击任何路由或刷新页面时,它会返回此错误。直到今天早上我工作得很好,除了一些 CSS 样式我没有改变任何东西。

这是我的 auth.js 文件:

import auth0 from "auth0-js"
import { navigate } from "gatsby"

const isBrowser = typeof window !== "undefined"

const auth = isBrowser
  ? new auth0.WebAuth({
      domain: process.env.AUTH0_DOMAIN,
      clientID: process.env.AUTH0_CLIENTID,
      redirectUri: process.env.AUTH0_CALLBACK,
      responseType: "token id_token",
      scope: "openid profile email",
    })
  : {}

const tokens = {
  accessToken: false,
  idToken: false,
  expiresAt: false,
}

let user = {}

export const isAuthenticated = () => {
  if (!isBrowser) {
    return
  }

  return localStorage.getItem("isLoggedIn") === "true"
}

export const login = () => {
  if (!isBrowser) {
    return
  }

  auth.authorize()
}

const setSession = (cb = () => {}) => (err, authResult) => {

  console.log(authResult);

  localStorage.setItem("userAuthID", authResult.idTokenPayload.sub)
  localStorage.setItem("userIdToken", 'Bearer '+authResult.idToken)
  if (err) {
    navigate("/")
    cb()
    return
  }

  if (authResult && authResult.accessToken && authResult.idToken) {
    let expiresAt = authResult.expiresIn * 1000 + new Date().getTime()
    tokens.accessToken = authResult.accessToken
    tokens.idToken = authResult.idToken
    tokens.expiresAt = expiresAt
    user = authResult.idTokenPayload
    localStorage.setItem("isLoggedIn", true)
    navigate("/account")
    cb()
  }

}

export const silentAuth = callback => {
  if (!isAuthenticated()) return callback()
  auth.checkSession({}, setSession(callback))
}

export const handleAuthentication = () => {
  if (!isBrowser) {
    return
  }

  auth.parseHash(setSession())
}

export const getProfile = () => {
  return user
}

export const logout = () => {
  localStorage.setItem("isLoggedIn", false)
  localStorage.removeItem("userIdToken");
  auth.logout()
}

这是我的 callback.js 文件:

import React, { Component } from 'react'
import { handleAuthentication } from "../utils/auth"
import { navigate } from 'gatsby';

export default class callback extends Component {

  componentDidMount() {
    handleAuthentication();
    setTimeout(() => {
      navigate('/account')
    }, 1500);
  }

  render() {
    return (
      <div>
        <div className="hero is-white is-fullheight">
          <div className="hero-body">
            <div className="container">
              <h1 className="title is-1 is-spaced has-text-centered logo-text">Fottom</h1>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

有人可以帮我找到这里缺少的东西吗?谢谢!

标签: reactjsgatsbyauth0

解决方案


我同意@mhSangar 的观点,您应该只在确保它不是null.

但我认为您遇到的问题还有另一层。您提到在您刷新之前一切正常,我假设是在尝试刷新令牌时。我的猜测是问题出在checkSession方法上。

目前,它被这样调用:

auth.checkSession({}, setSession(callback))

您必须将配置作为该方法的第一个参数传递(而不仅仅是一个空对象)。当我在我的应用程序中调用它时,我传递了以下参数:

{
  audience,
  callbackURL,
  clientID,
  domain
}

尝试将这些参数传递给auth.checkSession并查看是否可以解决它。

IE

export const silentAuth = callback => {
  if (!isAuthenticated()) return callback()
  auth.checkSession(
    {
      domain: process.env.AUTH0_DOMAIN,
      clientID: process.env.AUTH0_CLIENTID,
      redirectUri: process.env.AUTH0_CALLBACK,
      audience: YOUR_AUDIENCE (looks like AUTH0_DOMAIN/api/v2/)
    },
    setSession(callback)
  )
}

推荐阅读