2

我正在尝试在我的 Android(基于 KitKat)应用程序中实现 oauth 授权。

我已经准备好自己的 oauth2 服务器,基于 php(Symfony3 Framework + FOS Oauth Server Bundle)。现在我需要在 android 应用程序中进行授权。我想知道在互联网上,我没有找到任何可以帮助我进行授权的解决方案。有很多文档描述了使用 google 或其他社交服务的 OAUTH,但是,正如我所说,我有自己的 oauth 服务器。

我试图在移动应用程序中制作一些东西,但遇到了一些问题。Oauth 流程需要在应用程序中打开网络视图元素并接受我的应用程序使用我的网络帐户。此流程在我的服务器中有效,但我不知道如何在应用程序中执行此操作。我试图打开 web 视图,我正在传递身份验证流并正在获取代码,但它显示在 webview 中。我找到了方法——它捕捉了 web 视图加载的时刻,在这种情况下——我可以从 web 视图 URL 中捕捉一些参数,但是我在 web 中的 oauth 流在防火墙下。如果我没有在网络中获得授权 - 流程会将我重定向到登录页面,稍后 - 成功登录后 - 它会让我接受或拒绝使用我的帐户数据。所以,我不能使用 onPageFinished 或其他东西。

其他情况下,我可以通过传递登录名、密码、client_id、secret 和其他参数来获取 access_token。我正在考虑在应用程序中创建 2 个服务,首先将在本地检查 - 如果我的令牌未过期,如果是 - 它将运行第二个服务 - 刷新我的令牌 - 向我的 oauth 服务器(Web 应用程序)发出 http 请求. 但我在这里遇到了另一个问题。

我正在使用 Volley 库进行 http 调用。据我所知,volley 对 web 运行异步请求。我试图将我的请求转移到单独的类/服务中。但是我遇到了可空上​​下文的问题。好的。我决定在活动课上提出请求(不是很好的使用案例,但还可以),然后 - 我遇到了另一个问题。我已经为它定义了按钮和 onClick 监听器。我想在用户将登录名和密码输入 EditText 字段并在 onClick 中登录按钮后对用户进行身份验证 - 我正在检查 SharedPreferences 的 client_id,如果它为空 - 我想从 web 获取新的 oauth client_id,我是在 onCLickListener 中运行新的凌空请求。问题是 - 我无法正确获得响应。我的代码示例。

```signIn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
            String login = LoginView.getText().toString();
            String password = PasswordView.getText().toString();

            auth_dialog = new Dialog(LoginActivity.this);
            auth_dialog.setContentView(R.layout.auth_dialog);
            preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            preferences.edit().putString(getString(R.string.oauth_client_id), null).apply();
            String clientId = preferences.getString(getString(R.string.oauth_client_id), null);
            preferences.edit().putString(getString(R.string.user_login), login).apply();
            preferences.edit().putString(getString(R.string.user_password), password).apply();

            if(clientId == null){
                RequestQueue queue = Volley.newRequestQueue(context);
                SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
                String url = context.getString(R.string.url) + context.getString(R.string.url_token) + "?";
                url += "client_id=" + preferences.getString(context.getString(R.string.oauth_client_id), null) + "&";
                url += "client_secret=" + preferences.getString(context.getString(R.string.oauth_client_secret), null) + "&";
                url += "grant_type=" + context.getString(R.string.grant_type_password) + "&";
                url += "username=" + preferences.getString(context.getString(R.string.user_login), null) + "&";
                url += "password=" + preferences.getString(context.getString(R.string.user_password), null);

                StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response){
                        clientResponse = response;
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(context, "Request for getting Token failed", Toast.LENGTH_SHORT).show();
                    }
                });
                queue.add(stringRequest);
            }
            Log.d("VIOO_APP", clientResponse);// THIS IS THE PLACE WHERE ERROR HAPPENS
            token = getToken();
            Toast.makeText(getApplicationContext(), token.getAccessToken(), Toast.LENGTH_LONG).show();
        }
    });```

我想说的是所有变量都已定义——它只是来自按钮 onClick Listener 的代码部分。clientResponse在活动类中定义为全局变量的变量。

Ofcorse,我可以将我的逻辑放入响应语句中 - 当 volley 得到响应时 - 做我的事情,但我认为 - 稍后,我的代码将不可读,这不是构建应用程序结构的好方法。响应另一个请求而提出请求完全是胡说八道,依此类推……

当我的请求在另一个班级工作时,我有很好的案例。我在互联网上看到了一些例子——有些人如何尝试制作应用服务——通过 volley 发出请求,但现在可能这些信息并不实际。我发现的每个互联网案例都不起作用或提供无用的信息。

我认为这个挑战是无法取胜的。我尝试的所有东西都失败了,而且不起作用。
我希望,我完全解释了我的问题。谢谢你。

4

0 回答 0