【问题标题】:How to get github username in Firebase Github Auth如何在 Firebase Github Auth 中获取 github 用户名
【发布时间】:2021-10-31 06:43:39
【问题描述】:

我在使用 Firebase Github Auth 进行身份验证时尝试获取用户的用户名。但我无法得到它。我得到除了用户名之外的所有用户信息 这是我的代码:

import React, { useState, useContext, createContext, useEffect } from "react"
import { auth, createUserProfileDocument } from "../config/fbConfig"

const AuthContext = createContext()

export const useAuth = () => {
  return useContext(AuthContext)
}

export const AuthProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null)

  const provider = new auth.GithubAuthProvider()
  provider.addScope("read:user")
  const githubSignIn = () => {
    return auth().signInWithRedirect(provider)
  }

  const githubSignOut = () => {
    return auth().signOut()
  }

  useEffect(() => {
    const unsubscribe = auth().onAuthStateChanged(async (userAuth) => {
      // setCurrentUser(user);
      if (userAuth) {
        const useRef = await createUserProfileDocument(userAuth)
        useRef.onSnapshot((snapShot) => {
          console.log(snapShot)
          setCurrentUser({
            id: snapShot.id,
            ...snapShot.data(),
          })
        })
      } else {
        setCurrentUser(userAuth)
      }
    })
    return unsubscribe
  }, [])

  const value = {
    currentUser,
    githubSignIn,
    githubSignOut,
  }

  return <AuthContext.Provider value={value}> {children} </AuthContext.Provider>
}

fbConfig.js 文件代码

export const createUserProfileDocument = async (userAuth) => {
  if (!userAuth) return
  const userRef = firestore.doc(`users/${userAuth.uid}`)
  const snapShot = await userRef.get()

  if (!snapShot.exists) {
    const { email, photoURL, providerData } = userAuth
    const createdAt = new Date()
    getGitHubUserData(providerData[0].uid)
      .then(async (gitHubUserData) => {
        const username = gitHubUserData.login
        try {
          await userRef.set({
            email,
            photoURL,
            createdAt,
            displayName: providerData[0].displayName,
            username,
          })
        } catch (error) {
          console.log(error.message)
        }
      })
      .catch((err) => console.error("Don't forget error handling: ", err))
  }
  return userRef
}

请大家帮帮我。

【问题讨论】:

    标签: reactjs firebase firebase-authentication


    【解决方案1】:

    在对 GitHub 用户进行身份验证时,Firebase 会将以下信息存储在经过身份验证的用户的 ID 令牌 (auth.currentUser.providerData) 中:

    {
      // User's GitHub display name
      displayName: "Display Name",
      // User's public email address, null when private/out-of-scope
      email: null,
      // Phone numbers aren't applicable. Always null.
      phoneNumber: null,
      // Link to user's GitHub profile image, may be hosted on Gravatar
      photoURL: "https://avatars.githubusercontent.com/u/GITHUB_ID?v=4",
      // Always "github.com" - used to identify this ProviderData entry
      providerId: "github.com",
      // Numeric Github User ID
      uid: "GITHUB_ID"
    }
    

    请注意,这些数据均未提供用户在 GitHub 上的用户名。这主要是因为 GitHub 用户可以随意更改其用户名,并且 GitHub 不会向任何连接的应用程序发送“新用户名”通知以及 other side effects。

    考虑到这一点,要将 GitHub 用户 ID 解析为其用户名(在 GitHub 上称为 login),您可以使用用户 ID 查询 GitHub API:

    https://api.github.com/user/{idOrLogin}
    

    使用函数访问这些数据给出:

    async function getGitHubUserData(githubIdOrLogin) {
      return fetch(
        `https://api.github.com/user/${githubIdOrLogin}`,
        { headers: { 'Accept': 'application/json' } }
      )
        .then((response) => {
          if (!res.ok) {
            const err = new Error();
            err.response = res;
            if (res.status === 403 && res.headers.get('X-RateLimit-Remaining') == '0') {
              const resetsAtMS = Number(`${res.headers.get('X-RateLimit-Reset')}000`);
              err.message = `Rate limit exceeded, try again in ${Math.ceil((resetsAtMS-Date.now())/60000)}m`;
              err.code = "github/rate-limit-exceeded";
              err.resetsAt = resetsAtMS;
            } else if (res.status === 404) {
              err.message = `Could not find user data for github:${githubIdOrLogin}`);
              err.code = "github/not-found";
            } else { // add other cases if you want to handle them
              err.message = `Unexpected status code: ${res.status}`;
              err.code = "github/unknown";
            }
            return Promise.reject(err);
          }
    
          return res.json();
        });
    }
    

    那么你可以这样使用它:

    const githubProviderData = auth.currentUser
      .providerData
      .find((pd) => pd.providerId === 'github.com');
    
    getGitHubUserData(githubProviderData.uid)
      .then((githubUserData) => {
        // githubUserData.login will be their username
        // githubUserData.html_url will be a link to their profile
      })
      .catch((err) => console.error('Don\'t forget error handling: ', err));
    

    注意事项:

    • 在匿名使用此 API 时(即无需身份验证),您将受到(在撰写本文时)该 IP 地址每小时 60 次公共 API 调用的限制。 GitHub 的 rate-limit-exceeded 响应代码是 403 Forbidden。如果您绑定用户的身份验证令牌,则此限制会将该用户的呼叫次数提高到 5000 次/小时。如果您使用应用程序/服务器身份验证令牌,则此限制最高可达 12500 次调用/小时。有关详细信息,请参阅GitHub's documentation。
    • 如果您在用户的 GitHub 上做的不仅仅是获取用户名,那么还有一些使用 GitHub API 的节点包可用,例如官方的 @octokit/core、@octokit/request 和 @octokit/rest 包。有关更多信息,请参阅GitHub request documentation。 BVy 使用@octokit/request,上面的代码可以简化为just(但错误的处理方式不同):
    request('GET /users/{username}', { username: idOrLogin })
    

    【讨论】:

    • 您好,感谢您的回答。现在,我得到了一个用户名。您能否详细介绍一下“如果您绑定用户的身份验证令牌,则该限制会将该用户的呼叫次数提高到 5000 次/小时?”怎么做?我需要使用我的 GitHub 帐户身份验证令牌还是注册用户身份验证令牌(如果是,如何获得注册用户令牌)
    • 我添加了 fbConfig.js 文件代码。你能检查一下吗?我做得对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 2020-01-05
    相关资源
    最近更新 更多