使用android

时间:2017-06-19 16:53:34

标签: android authentication android-volley basic-authentication

任务
使用Android的身份验证管理器创建一次性登录功能。

当前流程
我目前正在使用Volley从表单中读取电子邮件和密码并将请求发送到服务器

需要更改
为了能够使用凭据创建一次性登录以使用Android身份验证管理器post

问题
1.我的问题在于在fetchTokenFromCredentials验证器类下实现getAuthToken方法。以下是代码段:

  @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse response,
            Account account, String authTokenType, Bundle options)
            throws NetworkErrorException {

        // We can add rejection of a request for a token type we
        // don't support here

        // Get the instance of the AccountManager that's making the
        // request
        final AccountManager am = AccountManager.get(mContext);

        // See if there is already an authentication token stored
        String authToken = am.peekAuthToken(account, authTokenType);

        // If we have no token, use the account credentials to fetch
        // a new one, effectively another logon
        if (TextUtils.isEmpty(authToken)) {
            final String password = am.getPassword(account);
            if (password != null) {
                authToken = fetchTokenFromCredentials(account.name, password, authTokenType)
            }
        }

        // If we either got a cached token, or fetched a new one, hand
        // it back to the client that called us.
        if (!TextUtils.isEmpty(authToken)) {
            final Bundle result = new Bundle();
            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
            result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
            return result;
        }

        // If we get here, then we don't have a token, and we don't have
        // a password that will let us get a new one (or we weren't able
        // to use the password we do have).  We need to fetch
        // information from the user, we do that by creating an Intent
        // to an Activity child class.
        final Intent intent = new Intent(mContext, LoginActivity.class);

        // We want to give the Activity the information we want it to
        // return to the AccountManager.  We'll cover that with the
        // KEY_ACCOUNT_AUTHENTICATOR_RESPONSE parameter.
        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
                response);
        // We'll also give it the parameters we've already looked up, or
        // were given.
        intent.putExtra(LoginActivity.ARG_IS_ADDING_NEW_ACCOUNT, false);
        intent.putExtra(LoginActivity.ARG_ACCOUNT_NAME, account.name);
        intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type);
        intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType);

        // Remember that we have to return a Bundle, not an Intent, but
        // we can tell the caller to run our intent to get its
        // information with the KEY_INTENT parameter in the returned
        // Bundle
        final Bundle bundle = new Bundle();
        bundle.putParcelable(AccountManager.KEY_INTENT, intent);
        return bundle;
    }  

以前我使用的是Volley,所以fetchTokenfromCredentials的实现如下所示。但是,我现在不能使用相同的实现,因为我需要'返回'一个身份验证字符串。 Volley以异步方式进行登录,因此即使我向下面的函数添加返回类型,它也将始终返回null。问题:我如何总结这种情况。我可以使用哪些替代品?

public void fetchTokenfromCredentials(String name, String password){    
JSONObject loginObject = new JSONObject();
            try{
                loginObject.put("email", email);
                loginObject.put("password", password);
            } catch(JSONException e) {
                e.printStackTrace();
            }
    // assume predefined url and params
                    JsonObjectRequest loginRequest = new HeaderRequest(Request.Method.POST, url + params, loginObject,
                            new Response.Listener<JSONObject>() {
                                @Override
                                public void onResponse(JSONObject response) {
                                    try {
                                        JSONObject headers = response.getJSONObject("headers");
    // A simple use class that stores the id, username etc.

                                    user = new User(response.getInt("id"), response.getString("name"), response.getString("authentication_token"), response.getString("email"));
// Previous code started a new main activity intent here

                            } catch(JSONException e){
                                e.printStackTrace();
                            }

                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d(TAG,"Failed response");
                }
            });
            RequestQueueSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(loginRequest);
        }

2 个答案:

答案 0 :(得分:0)

您可以使用Volley发出同步阻止请求。该请求将执行网络请求,同时阻止线程并允许您设置返回类型。

我对Volley(Retrofit,FTW!)不熟悉,但我很确定它是可行的。

查看同步请求的此答案 - https://stackoverflow.com/a/23808857

答案 1 :(得分:0)

这是我使用android Http Client Library编写fetchTokensFromCredentials(电子邮件,密码)函数的方法:

使用uri构建器

创建了URL
Uri builtUri = Uri.parse(AccountGeneral.LOGIN_QUERY).buildUpon()
        .build();
URL url = null;
try {
    url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
    e.printStackTrace();
}

// Stores result of the post response
        String result = null;

        // Create a JSON object for the email and password
        JSONObject loginObject = new JSONObject();
        try{
            loginObject.put("email", email);
            loginObject.put("password", password);
        } catch(JSONException e) {
            e.printStackTrace();
        }

        // Convert JSON to String
        String data = loginObject.toString();

        // Connection parameters
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.setRequestMethod("POST");

        try {

            //Start POST request - Write
            OutputStream outputStream = urlConnection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            writer.write(data);
            writer.close();
            outputStream.close();

            //Read response
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));

            String line = null;
            StringBuilder sb = new StringBuilder();

            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }

            bufferedReader.close();
            result = sb.toString();

            return result;

        } finally {
            urlConnection.disconnect();
        }