Интеграция Dropbox с использованием oAuth2 Url в React Native Android не работает с handleOpenUrl - PullRequest
0 голосов
/ 06 марта 2019

Я успешно интегрировал Dropbox oAuth2 и запись файлов в Dropbox в реагировать родной для iOS. Тот же код не работает для Android.

Я использую oAuth Url и handleOpenUrl в реагировать на родной язык для чтения входящих ссылок в Android.

Он открывает сайт Dropbox с помощью OAuthUrl и авторизует пользователя. На веб-сайте Dropbox, когда он запрашивает разрешение на доступ к файлам и папкам, когда мы нажимаем «Разрешить», он не открывает мое приложение.

Таким образом, управление не передается обратно и не вызывает handleOpenUrl метод. Не уверен, что мне не хватает.

Я также попробовал следующий метод:

Linking.getInitialURL().then((url) => {
        if (url) {
          console.log('Initial url is: ' + url);
          this.navigate(url);
      } 

Но это дает url как неопределенный.

В AndroidManifest.XML файле я добавил фильтр намерений и разрешения:

<uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https"
          android:host="www.dropbox.com" />

        <data android:scheme="https"
          android:host="www.dropbox.com/oauth2/authorize" />
<!-- Oauth2 redirect url set when dropbox app is created --> 
        <data android:scheme="com.companyname.appname.oauth"
          android:host="oauthredirect" />
      </intent-filter>

В тег Activity добавлен android: launchMode = "singleTask".

Ниже приведен фрагмент кода React Native:

export class DropboxAuthorize implements Authorize {
constructor() {

    this._handleOpenURL = this._handleOpenURL.bind(this);
  }

  // Authorize with Dropbox. Uses the device's browser to work through the Dropbox
  // OAuth 2 process, eventually recording a token and account ID if successful.
  public authorize(): Promise<void> {
    console.log("Authorization starting...");
    // Generate a random string for Dropbox's state param.
    // This helps us be sure a deep link into the app is indeed related to the request
    // we made to Dropbox.
    const stateValue = Math.random().toString();
     console.log("authorize stateValue",stateValue);
    // Open the Dropbox authorization page in the device browser
    return Linking.openURL(
      [
        'https://www.dropbox.com/oauth2/authorize',
        "?response_type=token",
        `&client_id=${DROPBOX.OAUTH_CLIENT_ID}`,
        `&redirect_uri=${DROPBOX.OAUTH_REDIRECT_URI}`,
        `&state=${stateValue}`
      ].join("")
    )
      .catch(err =>
        console.error(
          "An error occurred trying to open the browser to authorize with Dropbox:",
          err
        )
      )
      .then(() => {
        return new Promise((resolve, reject) => {
          const handleOpenURL = (event: { url: string }) => {
            console.log("event", event);
            this._handleOpenURL(event, stateValue)
              .then(() => {
                resolve();
              })
              .catch(reason => {
                reject(reason);
              })
              .then(() => {
                // "Finally" block
                // Remove deep link event listener
                Linking.removeEventListener("url", handleOpenURL);
                return;
              });

          };
           console.log("Hi there");
          // Add deep link event listener to catch when Dropbox sends the user back to the app.
          Linking.addEventListener("url", handleOpenURL);
        });
      });
  }

  private _handleOpenURL(
    event: { url: string },
    stateValue: string
  ): Promise<void> {
    console.log("Deep link event!", event);
    console.log("State Value",stateValue);
    const queryStringResult = event.url.match(/\#(.*)/);
    if (queryStringResult === null || queryStringResult.length < 2) {
      return Promise.reject(
        "Did not receive a query string as part of this deep link!"
      );
    }

    const [, queryString] = queryStringResult;
    const parsedQueryString = shittyQs(queryString);
    console.log ("parsedQueryString",parsedQueryString);
    if (parsedQueryString.error) {
      // There was an error!
      const errorCode = parsedQueryString.error;
      const errorDescription = parsedQueryString.error_description;

      console.error("Dropbox OAuth error! code:", errorCode);
      console.error("Error description:", errorDescription);

      return Promise.reject(
        `Could not authorize with Dropbox. Code: ${errorCode}`
      );
    }

      if (parsedQueryString.state){
        if (stateValue !== parsedQueryString.state) {
          // This value must match! This is a security feature of Dropbox's OAuth impl
          return Promise.reject("State parameter DID NOT MATCH!");
        }
      }
    // Otherwise: not an error!
    const accessToken = parsedQueryString.access_token;
    const accountId = parsedQueryString.account_id;

    // Persist accessToken and accountId
    return AsyncStorage.setItem(DROPBOX.ACCESS_TOKEN_STORAGE_KEY, accessToken)
      .then(() => {
     /*    return AsyncStorage.setItem(DROPBOX.ACCOUNT_ID_STORAGE_KEY, accountId);
      })
      .then(() => { */
        console.log(
          "Dropbox OAuth authorization success! Access Token:",
          accessToken
        );
       /*  console.log(
          "Dropbox OAuth authorization success! Account ID:",
          accountId
        ); */
        return;
      });
  }

Дайте мне знать, если какой-либо альтернативный метод доступен для чтения входящих ссылок.

1 Ответ

0 голосов
/ 29 мая 2019

Я решил эту проблему, создав URL-адрес перенаправления в моих приложениях dropbox: company_name: // open Затем в файле AndroidManifest.xml я добавил схему и хост, как показано ниже:

...