Search code examples
react-nativeoauth-2.0google-apiyoutube-apiexpo

React Native: Google OAuth Invalid parameter value for redirect_uri: Invalid scheme


I have some problems with authentication with Google OAuth2 in my react-native app. I'm using 'expo-auth-session' library for my authentification. I need get access token and then get Youtube profile. But i'm stuck with error "Invalid parameter value for redirect_uri: Invalid scheme"

My scheme in app.json:

"scheme": "com.liga.online"

My code is below:

import {
  makeRedirectUri,
  useAuthRequest,
  ResponseType,

} from "expo-auth-session";

const discoveryYoutube = {
    authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
    tokenEndpoint: 'https://oauth2.googleapis.com/token',
    revocationEndpoint: 'https://oauth2.googleapis.com/revoke'
};


/// Inside my React component
const [requestYoutube, responseYoutube, promptAsyncYoutube] = useAuthRequest(
    {
      responseType: ResponseType.Code,
      clientId: YOUTUBE_CLIENT_ID,
      scopes: ["https://www.googleapis.com/auth/youtube.readonly"],
      redirectUri: makeRedirectUri({
        native: "com.liga.online/callback",
      }),
    },
    discoveryYoutube
  );

When I press the button, callback is starting

  const signInYoutube = async () => {
    const response = await promptAsyncYoutube();
    console.log(response.data);
  }

But I get errorenter image description here

Any idea how I can fix it?

P.S. I tried fix it with library "expo-google-app-auth". I get access token, but when I try to get Youtube profile and get "Request failed with status code 403".

UPDATE 1

By the way about my connection to Youtube Profile.

I change something to get access token.

For example:

import * as Google from 'expo-google-app-auth';
import { startAsync } from 'expo-auth-session';


// Inside my React component

// When I press the button, callback is starting

const signInYoutube = async () => {

    const config = {
        androidClientId: YOUTUBE_CLIENT_ID
    };

    const { type, accessToken, user } = await Google.logInAsync(config);


    // I need again open my Browser for get Youtube data
    const response = await startAsync({
            authUrl: `https://www.googleapis.com/youtube/v3/channels?access_token=${accessToken}&part=snippet&mine=true&scope=https://www.googleapis.com/auth/youtube.readonly`,
            showInRecents: true
    });

    console.log(response.data);
}

But I get error

enter image description here

UPDATE 2

I wanted to see which data is loaded from AuthRequest. And I see pretty weird log. Redirect_uri is different from the set.enter image description here

RESOLUTION

When I add "https://www.googleapis.com/auth/youtube.readonly" in my scopes - i can get profile data. Another words below is my code.

import axios from 'axios';
import * as Google from 'expo-google-app-auth';

// Inside my React component

// Callback function

const signInYoutube = async () => {
    const config = {
        androidClientId: YOUTUBE_CLIENT_ID,
        scopes: ['https://www.googleapis.com/auth/youtube.readonly']
    };

    const { type, accessToken, user } = await Google.logInAsync(config);

    if (type === 'success') {
        const response = await axios.get(
                    `https://www.googleapis.com/youtube/v3/channels?part=id&mine=true&key=${encodeURI(YOUTUBE_API_KEY)}`,
                    {
                        headers: {
                            Authorization: `Bearer ${accessToken}`
                        }
                    }
                );

        setYoutubeData({ accessToken, user, youtubeId: response.data.items[0].id });
    }
};

IMPORTANT

Don't remember add in your project Youtube API v3


Solution

  • It looks like your expo environment is using the development redirect URI instead of the native one. Check out these docs for setting up the environment that will give you the native scheme you're looking for: https://docs.expo.io/guides/authentication/#standalone-bare-or-custom

    Also make sure that you register your custom scheme with Google: https://developers.google.com/identity/protocols/oauth2/native-app#redirect-uri_custom-scheme

    As for your Youtube example, you should be specifying the scopes in the call to Google.loginAsync, not the call to the Youtube API. scopes are requested during the authorization step, and your current authorization request doesn't include any. The relevant docs are here: https://docs.expo.io/versions/latest/sdk/google/#loginasync