【问题标题】:expo-auth-session/providers/google Google.useAuthRequestexpo-auth-session/providers/google Google.useAuthRequest
【发布时间】:2021-07-02 03:02:25
【问题描述】:

我在使用 Expo 管理的 React Native 应用程序中实施 Google Auth 时遇到问题。 当我尝试登录时,响应不包含 IdToken 或用户信息,我不明白为什么......

这是我的代码:

 import * as Google from 'expo-auth-session/providers/google';
 
 const [request1, response1, promptAsync1] = Google.useAuthRequest({
    expoClientId: 'my-expo-id',
    iosClientId: 'my-ios-id',
  });

  React.useEffect(() => {
    if (response1?.type === 'success') {
      const { authentication } = response1;
    }
  }, [response]);

  console.log('reponse', response1)
  
  return (
  <View>
          <TouchableOpacity onPress={() => promptAsync1()}>
            <Text style={styles.connexionText}>Connect with Google</Text>
          </TouchableOpacity>
  </View>
  
  )

这是回复:

reponse Object {
  "authentication": TokenResponse {
    "accessToken": "ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN",
    "expiresIn": "3599",
   ** "idToken": undefined, **
    "issuedAt": 1617701320,
    ** "refreshToken": undefined, **
    "scope": "email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email",
    "state": "RwgjNwizdQ",
    "tokenType": "Bearer",
  },
  "error": null,
  "errorCode": null,
  "params": Object {
    "access_token": "ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN",
    "authuser": "0",
    "exp://172.20.10.3:19000/--/expo-auth-session": "",
    "expires_in": "3599",
    "prompt": "none",
    "scope": "email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email",
    "state": "RwgjNwizdQ",
    "token_type": "Bearer",
  },
  "type": "success",
  "url": "exp://172.20.10.3:19000/--/expo-auth-session#state=RwgjNwizdQ&access_token=ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX
_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN&token_type=Bearer&expires_in=3599&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20openid%20https:/
/www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none",
}

非常感谢您的帮助!

【问题讨论】:

  • 是的,最糟糕的是,使用谷歌进行身份验证的旧方法确实提供了 idToken——你不能将它用于网络:/。如果您只是将您的应用范围缩小到仅适用于 android 和 ios,我建议您使用较旧的方法 (expo-google-app-auth)。如果我找到解决办法,我会在这里报告。

标签: react-native expo google-authentication


【解决方案1】:

因此,如果您正在寻找的只是 idToken,那么它是可能的。你需要像这样修改你的代码:

 const [request, response, promptAsync] = Google.useAuthRequest({
    *responseType: "id_token",*
    expoClientId: 'my-expo-id',
    iosClientId: 'my-ios-id',
  });

您还必须访问“params”键而不是“authentication”,这将显示大部分为 null :)。对我来说它至少有效,因为其余的信息是无用的。 HTH!

编辑:我意识到我需要获取访问令牌才能在我的应用程序中使用谷歌驱动器,因此现在我需要两个令牌并在此处提交错误报告 https://github.com/expo/expo/issues/12808 以尝试解决此问题。

【讨论】:

  • 您是如何获得这些信息的?我遇到了同样的问题,花了一整天的时间寻找这个,我只在这里找到了它。顺便谢谢你救了我!
  • 不客气。很多只是搜索与问题相关的东西,所以我不只是寻找谷歌端点,而是搜索了一般的 authSessions 并且有足够的例子。在某些时候,我也只是在阅读 github 文档(仅供参考,还有另一个名为 useIdTokenAuthRequest insead of useAuthRequest 的函数没有很好的文档记录,但它与添加 responseType 完全相同——我只在 github 中发现了这一点代码)
  • 顺便说一句,感谢 github 上的呐喊 @fermmm 哈哈
  • 是不是也有类似的方式,这样会包含一个刷新令牌?
【解决方案2】:

您可以像这样获取用户详细信息:

  1. 首先,从响应中获取访问令牌:

    const accessToken = response.authentication.accessToken

  2. 使用您在步骤 1 中获得的 accessToken 向以下端点发送 GET 请求:

axios.get('https://www.googleapis.com/oauth2/v3/userinfo?
access_token='+ACCESS-TOKEN-HERE)
    .then(function(response){
        const userDetails = response.data
        console.log(userDetails)
    })

【讨论】:

    【解决方案3】:

    只想在这里补充一下,霍华德的回答中提到的 id_token(Google 颁发的 id_token)是一个 JWT,您可以在 jwt.io 或使用 jwt-decode 之类的 jwt-decode 库进行解码(https://github.com/auth0/jwt-decode)或做这样的事情:

          import { Buffer } from "buffer";
          // get response object 
          const id_token = response.params.id_token;
    
          // need to decode the id_token(jwt) to get the user object, jwt issued by Google
          const jwt_parts = id_token
            .split(".")
            .map((jwt_part) =>
              Buffer.from(
                jwt_part.replace(/-/g, "+").replace(/_/g, "/"),
                "base64"
              ).toString()
            );
          const user = JSON.parse(jwt_parts[1]); // get user object after jwt decoded
          console.log(user);
    
    

    用户将具有以下属性:

    interface GoogleUserFromJWTPayload {
      iss: string;
      azp: string;
      aud: string;
      sub: string;
      hd: string;
      email: string;
      email_verified: boolean;
      nonce: string;
      name: string;
      picture: string;
      given_name: string;
      family_name: string;
      locale: string;
      iat: number;
      exp: number;
      jti: string;
    }
    
    

    但是,如果您同时需要 id_token 和 accessToken ,那么目前它仍然是一个问题/限制吗?: https://github.com/expo/expo/issues/12808

    【讨论】:

      猜你喜欢
      • 2021-02-10
      • 2022-07-17
      • 2022-10-18
      • 2020-09-08
      • 2022-08-10
      • 2021-02-22
      • 2022-12-03
      • 2021-07-03
      • 2022-10-13
      相关资源
      最近更新 更多