Trouble using expo-auth-session

298 Views Asked by At

I've managed to successfully log in to google using the web build from expo but when I try and login through the Expo Go app I get the error message

"You can't sign in to this app because it doesn't comply with Google OAuth 2.0 policy for keeping apps secure."

Error 400:invalid_request Request details: redirect_uri=exp://192.168.1.66:8081

Also when I try and login on a built android app it allows me to successfully log in but then doesn't redirect me back to the app, instead it take me to the google home page within the popup window. When I exit the popup it hasn't saved my login info.

Any help would be much appreciated

Here's the code

import Home from "./Home";
import { useEffect, useState } from "react";
import * as WebBrowser from "expo-web-browser";
import * as Google from "expo-auth-session/providers/google";
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as AuthSession from "expo-auth-session";
import {
  Button,
  View,
  ActivityIndicator,
  StyleSheet,
  Text,
} from "react-native";
import { createMongoUser, getMongoUser } from "./HTTP";
import LoginScreen from "./Views/LoginScreen";
import config from "./HTTP/config.json";
import registerNNPushToken, { getPushDataInForeground } from "native-notify";
import Constants from "expo-constants";

WebBrowser.maybeCompleteAuthSession();

const EXPO_REDIRECT_PARAMS = {
  useProxy: true,
  projectNameForProxy: "@leonhick/CafeRewards",
};
const NATIVE_REDIRECT_PARAMS = { native: "com.leonhick.caferewards://" };
const REDIRECT_PARAMS =
  Constants.appOwnership === "expo"
    ? EXPO_REDIRECT_PARAMS
    : NATIVE_REDIRECT_PARAMS;
const redirectUri = AuthSession.makeRedirectUri(REDIRECT_PARAMS);

let skipLoginUser = {
  _id: { $oid: "657b867e87316912d382fef0" },
  email: "[email protected]",
  verified_email: true,
  name: "Leon Hickingbotham",
  given_name: "Leon",
  family_name: "Hickingbotham",
  picture:
    "https://lh3.googleusercontent.com/a/ACg8ocLgcUmdvrgOtfzhihWHxlobB1FKWrtdCw2gjuuW678CgF8=s96-c",
  locale: "en",
  companies: [
    {
      name: "Real test",
      id: "5164a144-61f6-4538-89e5-081fa8ad7424",
      rewards: "0.00",
    },
    {
      name: "Test company real 2",
      id: "bebee9d9-ef59-48e1-8d6b-67bc061ef2de",
      rewards: "1.20",
    },
  ],
};

export default function () {
  // registerNNPushToken(config.appId, config.appToken);
  const [tempUser, setTempUser] = useState(null);
  const [userInfo, setUserInfo] = useState(
    // skipLoginUser
    null
  );
  const [request, response, promptAsync] = Google.useAuthRequest(
    {
      androidClientId:
        "285363570582-vq6713tddf62uigs9stumoqmaul8rh2i.apps.googleusercontent.com",
      // iosClientId:
      //   "285363570582-3beu4apl3e73adqm9f9vu30l8bh0gj9q.apps.googleusercontent.com",
         webClientId:
      //   "285363570582-0v78j4ql35fe0j133uinods9iknjgius.apps.googleusercontent.com",
      expoClientId:
        "285363570582-lfn286l4sqo410hbsuhmos98cj8a9d8m.apps.googleusercontent.com",
    },
    redirectUri
  );
  const [isLoading, setIsLoading] = useState(true);

  const getUserInfo = async (token) => {
    if (!token) return;
    console.log("found token");
    try {
      const response = await fetch(
        "https://www.googleapis.com/userinfo/v2/me",
        {
          headers: { Authorization: `Bearer ${token}` },
        }
      );
      console.log("hit googleapi");
      const user = await response.json();
      setTempUser(user);
      await AsyncStorage.setItem("@user", JSON.stringify(user));
      console.log("storing user in cache");
      await handleMongoDb(user);
    } catch (error) {
      // handle errors
    }
  };

  async function wrapLoader() {
    // console.log(response);
    setIsLoading(true);
    await handleSignInWithGoogle();
    setIsLoading(false);
  }

  useEffect(() => {
    wrapLoader();
  }, [response]);

  async function handleMongoDb(user) {
    // handle mongoDb here
    console.log("hitting mongoDB");
    let { id, ...usableUser } = user;

    console.log(user.email);

    let fullUser = await getMongoUser(user.email);

    if (!fullUser || (fullUser.error && fullUser.code === 404)) {
      // create new entry in MongoDb
      let newFullUser = await createMongoUser(usableUser);
      setUserInfo(newFullUser);
    } else {
      // save user locally
      setUserInfo(fullUser);
    }
  }

  async function handleSignInWithGoogle() {
    console.log("trying to auth");
    const user = await AsyncStorage.getItem("@user");
    if (!user) {
      if (response?.type === "success") {
        console.log("trying to get access token");
        await getUserInfo(response.authentication.accessToken);
      }
      return;
    } else {
      await handleMongoDb(JSON.parse(user));
    }
  }

  return userInfo ? (
    <Home
      userInfo={userInfo}
      setUserInfo={setUserInfo}
      handleMongoDb={handleMongoDb}
    />
  ) : isLoading ? (
    <View style={styles.container}>
      <ActivityIndicator />
    </View>
  ) : tempUser ? (
    <View>
      <Text>{JSON.stringify(tempUser)}</Text>
    </View>
  ) : (
    <LoginScreen promptAsync={promptAsync} />
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
  },
});

Here's my app.json

{
  "expo": {
    "name": "Cafe Rewards",
    "slug": "CafeRewards",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "assetBundlePatterns": ["**/*"],

    "ios": {
      "supportsTablet": true,
      "googleServicesFile": "./Info.plist",
      "bundleIdentifier": "com.leonhick.caferewards"
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      },
      "package": "com.leonhick.caferewards"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "scheme": "com.leonhick.caferewards",
    "extra": {
      "eas": {
        "projectId": "0e18f137-da1b-4325-bc81-adaa72e62ca3"
      }
    }
  }
}

I've tried to set the useProxy option and also to provide an expoClientId but it defaults to the androidClientId in the expo app.

I'm expecting to be able to login to google through the Expo Go app, and to have the web browser redirect to my app in the .apk built app

2

There are 2 best solutions below

0
On

I had the same configuration as yours, a little bit different is in the scheme value in app.json. So this issue is regarding the deep linking mechanism that currently has no longer supported due to the risk of app impersonation. To solve this what you need is enable scheme manually in your OAUTH credentials.

  1. Go to credentials page
  2. Select your current OAUTH credentials
  3. Open Advanced setting
  4. Check Enable custom URI scheme Enable scheme

For more details you can check reference here: https://developers.google.com/identity/protocols/oauth2/native-app#redirect-uri_custom-scheme

0
On

could it be that you are logging in , on expo go, through a web browser as opposed to your app? and that google chrome or other trusted browsers are not installed in google play on your expo go? I tried installing google chrome first on my expo go then ran my app and it worked ok