使用Google的Soundcloud API移动OAUTH登录无法在Android上运行

使用Google的Soundcloud API移动OAUTH登录无法在Android上运行,第1张

概述我正在使用移动SoundCloudWeb身份验证页面登录到SoundCloud的Android应用程序上工作.SoundCloud移动Web身份验证页面为您提供了使用SoundCloud,Facebook或Google登录的三个选项.该界面如下所示:到目前为止,我可以使用SoundCloud和Facebook凭据登录,但是使用Google时失败.这是我正

我正在使用移动SoundCloud Web身份验证页面登录到SoundCloud的Android应用程序上工作. SoundCloud移动Web身份验证页面为您提供了使用SoundCloud,Facebook或Google登录的三个选项.该界面如下所示:

到目前为止,我可以使用SoundCloud和Facebook凭据登录,但是使用Google时失败.这是我正在做的删节版:

public class SoundCloudActivity extends Activity {    ...    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.twitter_login_layout);        ...        loadingProgressbar = (Progressbar) findVIEwByID(R.ID.loading_progressbar);        WebVIEw webVIEw = (WebVIEw) findVIEwByID(R.ID.login_webvIEw);        webVIEw.setVerticalScrollbarEnabled(true);        webVIEw.setHorizontalScrollbarEnabled(true);        webVIEw.setWebVIEwClIEnt(new SoundclouDWebVIEwClIEnt());        webVIEw.getSettings().setJavaScriptEnabled(true);        webVIEw.getSettings().setAllowfileAccess(true);        webVIEw.getSettings().setPluginState(PluginState.ON);        webVIEw.getSettings().setJavaScriptCanopenwindowsautomatically(true);        authUrl = API.wrapper.authorizationCodeUrl(Endpoints.CONNECT, Token.ScopE_NON_EXPIRING).toString();        webVIEw.loadUrl(authUrl);    }    private class SoundclouDWebVIEwClIEnt extends WebVIEwClIEnt {        public boolean shouldOverrIDeUrlLoading(WebVIEw vIEw, String url) {            Log.d(TAG, "shouldOverrIDeUrlLoading(): url: "+url);            if (url.startsWith(REDIRECT_URI.toString())) {                Uri result = Uri.parse(url);                new Thread(new Runnable() {                    @OverrIDe                    public voID run() {                        try {                            token = API.wrapper.authorizationCode(code, Token.ScopE_NON_EXPIRING);                        } catch (IOException e) {                            e.printstacktrace();                        }                        ...                    }                }).start();                return true;            } else if (url.startsWith("authorize")) {                return false;            } else if (url.startsWith("http")) {                vIEw.loadUrl(url);            }            return true;        }        @OverrIDe        public voID onReceivedError(WebVIEw vIEw, int errorCode,                String description, String failingUrl) {            Log.d(TAG, "Call one rror with error: "+description);            super.onReceivedError(vIEw, errorCode, description, failingUrl);        }        @OverrIDe        public voID onPageStarted(WebVIEw vIEw, String url, Bitmap favicon) {            Log.d(TAG,"onPageStarted(): url: "+url+" favicon: "+favicon);            loadingProgressbar.setVisibility(Progressbar.VISIBLE);            super.onPageStarted(vIEw, url, favicon);        }        @OverrIDe        public voID onPageFinished(WebVIEw vIEw, String url) {            loadingProgressbar.setVisibility(Progressbar.GONE);            super.onPageFinished(vIEw, url);        }    }}

选择使用Google时,它会将我重定向到熟悉的Google登录页面.然后,当我输入用户名和密码时,它会将我重定向到空白页面,并且不执行任何 *** 作,包括不向我提供身份验证令牌.这是登录后生成的空白页面的示例URL:

https://accounts.google.com/o/oauth2/auth?client_id=984739005367.apps.googleusercontent.com&redirect_uri=postmessage&response_type=code%20token%20id_token%20gsession&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=539399140%7C0.873620491&access_type=offline&request_visible_actions=http%3A%2F%2Fschemas.google.com%2FAddActivity%20http%3A%2F%2Fschemas.google.com%2FListenActivity%20http%3A%2F%2Fschemas.google.com%2FCreateActivity&after_redirect=keep_open&cookie_policy=single_host_origin&include_granted_scopes=true&proxy=oauth2relay763648117&origin=https%3A%2F%2Fsoundcloud.com&

我想知道WebVIEw中是否缺少我需要的设置.我已经必须使其他人能够使用SoundCloud移动网页中的其他功能.任何建议将不胜感激.

解决方法:

因此,Google使用跨站点JavaScript注入来完成身份验证过程,这要求在Google身份验证过程中仍打开SoundCloud登录窗口.要解决此问题,您需要强制/允许Google身份验证进入新的WebvIEw窗口.我在github上创建了一个演示项目,该项目显示了整个过程here.

这是完成工作的课程,请查看全文以获取更多详细信息:

package com.bulwinkel.soundcloudlogin;import androID.content.Context;import androID.content.DialogInterface; import androID.graphics.Bitmap;import androID.graphics.color;import androID.net.Uri;import androID.os.Build;import androID.os.Bundle;import androID.os.Message;import androID.support.v7.app.AlertDialog;import androID.support.v7.app.AppCompatActivity;import androID.util.Log;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.webkit.cookieManager;import androID.webkit.cookieSyncManager;import androID.webkit.WebChromeClIEnt;import androID.webkit.WebSettings;import androID.webkit.WebVIEw;import androID.webkit.WebVIEwClIEnt;import androID.Widget.FrameLayout;import androID.Widget.Progressbar;import androID.Widget.relativeLayout;public class SoundCloudLoginActivity extends AppCompatActivity {  private static final String TAG = SoundCloudLoginActivity.class.getSimplename();  //todo - create a project in the SoundCloud developer portal: https://soundcloud.com/you/apps/  private static final String CALLBACK_SCHEME = "soundcloudlogindemo://authentication.complete"; //todo - replace  private static final String CLIENT_ID = "e64276127b07b38ddfaf1ee458ffc2ac"; //todo - replace  private static final String STATE = SoundCloudLoginActivity.class.getCanonicalname();  @OverrIDe protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    // clear the cookies to make sure the that the user is properly logged out    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP_MR1) {      final cookieManager cookieManager = cookieManager.getInstance();      cookieManager.removeAllcookies(null);      cookieManager.flush();    } else {      cookieSyncManager.createInstance(getApplicationContext()).startSync();      final cookieManager cookieManager = cookieManager.getInstance();      cookieManager.removeAllcookie();      cookieManager.removeSessioncookie();    }    // SoundCloud oauth url    final Uri authUri = new Uri.Builder().scheme("https")        .authority("soundcloud.com")        .appendpath("connect")        .appendqueryParameter("scope", "non-expiring")        .appendqueryParameter("response_type", "code")        .appendqueryParameter("state", STATE)        .appendqueryParameter("display", "popup")        .appendqueryParameter("clIEnt_ID", CLIENT_ID)        .appendqueryParameter("redirect_uri", CALLBACK_SCHEME)        .build();    Log.d(TAG, "https://soundcloud.com/connect?scope=non-expiring&response_type=code&state=Boxset.soundCloudLoginActivity&display=popup&clIEnt_ID=6d483c5c02062da985379c36b5e7da95&redirect_uri=http%3A%2F%2Fwonder.fm%2Fincoming%2Fsoundcloud%2Fauth%2F");    Log.d(TAG, authUri.toString());    // we need a handle to this to add the second webvIEw during Google plus login    final FrameLayout container = (FrameLayout) findVIEwByID(R.ID.container);    // progress hud adds itself to the vIEw hIErarchy    final LoadingHud loadingHud = new LoadingHud(container);    final WebVIEw webVIEw = createWebVIEw(this);    webVIEw.loadUrl(authUri.toString());    final WebVIEwClIEnt webVIEwClIEnt = new WebVIEwClIEnt() {      // need to use the depricated method if you are supporting less than API 21      @OverrIDe public boolean shouldOverrIDeUrlLoading(WebVIEw vIEw, String url) {        //GUARD - been stung by this        if (url == null) return false;        //GUARD - check if we have got our callback url yet        // this occurs when navigating to facebook and Google plus login screens        if (!url.contains(CALLBACK_SCHEME)) return false;        final Uri uri = Uri.parse(url);        //GUARD        // the state query parameter is echoed back to us so we        // kNow that the code is coming from a legitimate source        final String state = uri.getqueryParameter("state");        if (!STATE.equals(state)) return false;        //GUARD        final String code = uri.getqueryParameter("code");        if (code == null) {          // something went wrong during the auth process          // you need to handle this          Log.d(TAG, "No code returned from auth process");          return false;        }        // you Now have you code to use in the next step of the oauth process        Log.i(TAG, "code = " + code);        new AlertDialog.Builder(vIEw.getContext())            .setTitle("Auth Successful")            .setMessage("Code: " + code)            .setPositivebutton("OK", new DialogInterface.OnClickListener() {              @OverrIDe public voID onClick(DialogInterface dialogInterface, int i) {                finish();              }            })            .create()            .show();        return true;      }      @OverrIDe public voID onPageStarted(WebVIEw vIEw, String url, Bitmap favicon) {        super.onPageStarted(vIEw, url, favicon);        loadingHud.show();      }      @OverrIDe public voID onPageFinished(WebVIEw vIEw, String url) {        super.onPageFinished(vIEw, url);        loadingHud.hIDe(true);      }    };    webVIEw.setWebVIEwClIEnt(webVIEwClIEnt);    // require for Google login    // Google login requires that the SoundCloud login window be open at the same time    // as it uses cross window/site JavaScript injection to pass information back to    // SoundCloud on completion    webVIEw.setWebChromeClIEnt(new WebChromeClIEnt() {      @OverrIDe public boolean onCreateWindow(WebVIEw vIEw, boolean isDialog, boolean isUserGesture,          Message resultMsg) {        // this WebVIEw has to has the same settings as the original for        // the cross site JavaScript injection to work        final WebVIEw GoogleSignInWebVIEw = createWebVIEw(vIEw.getContext());        GoogleSignInWebVIEw.setWebChromeClIEnt(this);        GoogleSignInWebVIEw.setWebVIEwClIEnt(webVIEwClIEnt);        container.addVIEw(GoogleSignInWebVIEw);        // this is the glue code that wires the original webvIEw        // and the new webvIEw together so they can communicate        final WebVIEw.WebVIEwTransport transport = (WebVIEw.WebVIEwTransport) resultMsg.obj;        transport.setWebVIEw(GoogleSignInWebVIEw);        resultMsg.sendToTarget();        // this advises that we have actually created and displayed the new window        return true;      }      // since we added the window we also have to handle removing it      @OverrIDe public voID onCloseWindow(WebVIEw window) {        container.removeVIEw(window);      }    });    container.addVIEw(webVIEw);  }  /**   * @param context  the WebVIEw must be given an activity context (instead of application context)   *                 or it will crash in versions less than 4.4   *   * @return a {@link WebVIEw} suitable for the soundcloud login process   */  private static WebVIEw createWebVIEw(Context context) {    final WebVIEw webVIEw = new WebVIEw(context);    final WebSettings settings = webVIEw.getSettings();    // this allows the username and password valIDation to work    settings.setJavaScriptEnabled(true);    // these 2 are for login with Google support    // which needs to open a second window    settings.setJavaScriptCanopenwindowsautomatically(true);    settings.setSupportMultiplewindows(true);    // prevent caching of user data    settings.setSaveFormData(false);    // prevents the webvIEw asking the user if they want to save their password    // needed for pre 18 devices    settings.setSavePassword(false);    return webVIEw;  }  private static class LoadingHud {    private final relativeLayout container;    public LoadingHud(VIEwGroup parentVIEw) {      container = new relativeLayout(parentVIEw.getContext());      container.setAlpha(0);      parentVIEw.addVIEw(container);      final VIEwGroup.LayoutParams layoutParams = container.getLayoutParams();      layoutParams.height = VIEwGroup.LayoutParams.MATCH_PARENT;      layoutParams.wIDth = VIEwGroup.LayoutParams.MATCH_PARENT;      container.setLayoutParams(layoutParams);      addMask(container);      addProgressbar(container);    }    private voID addMask(relativeLayout container) {      final VIEw vIEw = new VIEw(container.getContext());      vIEw.setBackgroundcolor(color.WHITE);      vIEw.setAlpha(.5f);      container.addVIEw(vIEw);      final relativeLayout.LayoutParams layoutParams =          (relativeLayout.LayoutParams) vIEw.getLayoutParams();      layoutParams.height = VIEwGroup.LayoutParams.MATCH_PARENT;      layoutParams.wIDth = VIEwGroup.LayoutParams.MATCH_PARENT;      vIEw.setLayoutParams(layoutParams);    }    private voID addProgressbar(relativeLayout container) {      final Progressbar progressbar = new Progressbar(container.getContext());      container.addVIEw(progressbar);      final relativeLayout.LayoutParams layoutParams =          (relativeLayout.LayoutParams) progressbar.getLayoutParams();      layoutParams.addRule(relativeLayout.CENTER_IN_PARENT);      progressbar.setLayoutParams(layoutParams);    }    voID show() {      container.bringToFront();      container.animate().Alpha(1f).start();    }    voID hIDe(Boolean animated) {      float noAlpha = 0f;      if (animated) {        container.animate().Alpha(noAlpha).start();      } else {        container.setAlpha(noAlpha);      }    }  }}
总结

以上是内存溢出为你收集整理的使用Google的Soundcloud API移动OAUTH登录无法在Android上运行全部内容,希望文章能够帮你解决使用Google的Soundcloud API移动OAUTH登录无法在Android上运行所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1088408.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存