認証エラー:これらの課題のいずれにも応答できません:{} Android-401 Unauthorized
私はこのリンクから参照を取りました AndroidでDefaultHttpClientでHttpPostを使用するときの認証エラー
Drupalに裏打ちされたAndroidアプリに取り組んでいます。その点で、Androidアプリからdrupalウェブサイト(JSON形式のウェブサービス)にデータを送信しています。これで、Drupal WebサービスからJSONデータを読み取り、Androidアプリケーションに書き込むことができます。しかし、Androidからdrupalに書き込む際に問題が発生すると、ステータスコードで応答が生成されます
401無許可
Androidネイティブアプリからは401を生成しますが、phonegapから-AndroidからAJAXリクエストを開始すると、完全に機能し、drupal Webサイトに記事またはページを書き込みます。つまり、Webサービスは完全に機能します。
私のphonegap Androidアプリは完全に機能しますAndroidネイティブJavaアプリケーションに問題がありますAndroid2.3.4でAndroidアプリケーションを実行しています-> Samsung Galaxy S Plus-Samsung GT- I9001
これがJava Android用の私のコードです。
==============================
String url = "XXX";
strResponse1 = makeWebForPostIdea(url,title,body);
public static String makeWebForPostIdea(String url, String title,String body)
{
JSONStringer jsonobject = null;
JSONObject json = null;
JSONObject jsonnode = null;
DefaultHttpClient client = new DefaultHttpClient();
Credentials creds = new UsernamePasswordCredentials("username", "password");
client.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_Host, AuthScope.ANY_PORT), creds);
HttpPost post = new HttpPost(url);
System.out.println("value of the post =============> "+post);
try {
JSONObject jsonvalue = new JSONObject();
jsonvalue.put("value", body.toString());
JSONArray array = new JSONArray();
array.put(jsonvalue);
jsonnode = new JSONObject();
jsonnode.put("und", array);
System.out.println("@@@@@@2 jsonnode=======>"+jsonnode.toString());
} catch (JSONException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
try {
jsonobject = new JSONStringer().array().object().key("und").object().key("0").object().key("value").value(body).endObject().endObject().endObject().endArray();
System.out.println("=============>"+jsonobject);
} catch (JSONException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("type","page"));
params.add(new BasicNameValuePair("title",title));
params.add(new BasicNameValuePair("language","und"));
params.add(new BasicNameValuePair("body",jsonobject.toString()));
System.out.println("value of the params =============> "+params);
UrlEncodedFormEntity formEntity = null;
try {
formEntity = new UrlEncodedFormEntity(params);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
post.setEntity(formEntity);
try {
HttpResponse response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("=========> statusCode post idea=====> "+statusCode);
if (statusCode == HttpStatus.SC_OK)
{
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
return iStream_to_String(is);
}
else
{
return "Hello This is status ==> :"+String.valueOf(statusCode);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static String iStream_to_String(InputStream is1) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is1), 4096);
String line;
StringBuilder sb = new StringBuilder();
try {
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String contentOfMyInputStream = sb.toString();
return contentOfMyInputStream;
}
}
}
これが私が入手しているlogcatです。
08-09 12:41:29.063: I/System.out(336): value of the post =============> org.Apache.http.client.methods.HttpPost@4053c3c8
08-09 12:41:29.093: I/System.out(336): @@@@@@2 jsonnode=======>{"und": [{"value":"ddddddd"}]}
08-09 12:41:29.093: I/System.out(336): =============>[{"und":{"0":{"value":"ddddddd"}}}]
08-09 12:41:29.103: I/System.out(336): value of the params =============> [type=page, title=hhhh, language=und, body=[{"und":{"0":{"value":"ddddddd"}}}]]
08-09 12:41:30.913: W/DefaultRequestDirector(336): Authentication error: Unable to respond to any of these challenges: {}
08-09 12:41:30.913: I/System.out(336): =========> statusCode post idea=====> 401
08-09 12:41:30.924: I/System.out(336): =========> Response from post idea => Hello This is status ==> :401
これが私のPhoneGapAjaxリクエストです。完全に機能します。
$('#page_node_create_submit').live('click',function(){
var title = $('#page_node_title').val();
//if (!title) { alert('Please enter a title.'); return false; }
var body = $('#page_node_body').val();
//if (!body) { alert('Please enter a body.'); return false; }
// BEGIN: drupal services node create login (warning: don't use https if you don't have ssl setup)
$.ajax({
url: "XXX",
type: 'post',
data: 'node[type]=page&node[title]=' + encodeURIComponent(title) + '&node[language]=und&node[body][und][0][value]=' + encodeURIComponent(body),
dataType: 'json',
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('page_node_create_submit - failed to login');
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (data) {
$.mobile.changePage("index.html", "slideup");
}
});
// END: drupal services node create
return false;
});
================================================= ===============================
私はエラーのためにApachehttpclientのさまざまな方法を試しました。この間、私はいくつかの調査を行い、グーグルで検索し、いくつかの興味深いものを見つけました。
1stAndroid-Googleは、コードで使用しているApacheHttpClientを公式に推奨していないことがわかりました。このリンクを確認してください。 DalvikチームのJesseWilsonからのリンクメッセージ。彼らはDefaultHttpClientの代わりにHttpURLConnectionを使用することを提案し、AndroidチームはApachehttpclientを開発しないと書いています。だから私が使っている古いバージョンです。
http://Android-developers.blogspot.in/2011/09/androids-http-clients.html
2番目このリンクから見つけたもの。これは、AndroidがApacheのHttpClient 4.0 Beta2とともに出荷されていることを示唆しています。これには、基本認証に関しては落とし穴があります。私が使用している認証方法は次のとおりです。このリンクから見つけたHttpClient3.xの。リンクを確認してください。 http://hc.Apache.org/httpclient-3.x/authentication.html#Preemptive_Authentication
したがって、バージョンの問題。
http://dlinsin.blogspot.in/2009/08/http-basic-authentication-with-Android.html
私はまた、この問題の潜在的な解決策とのいくつかのリンクを見つけました。
http://ogrelab.ikratko.com/using-newer-version-of-httpclient-like-4-1-x/
これらのリンクから、Apache HttpClientを最新の安定バージョンにアップグレードすると、この問題は解決できると結論付けました。
ただし、AndroidチームがApache httpclientのサポートを正式に停止したため、これは直接不可能です。
このリンクで解決することが可能かもしれません。試したことはありませんが、取り組んでいます。
これは、Androidでhttpclientバージョンをアップグレードするのに役立つライブラリです。
他の解決策は、HttpURLConnectionを使用することです。私もそれに取り組んでいます。
しかし、ここスタックオーバーフローとインターネットのほとんどの人は、AndroidでDefaultHttpCLientを使用しているようです。そしてもちろん、ログイン、登録、サーバーとセッションからの読み取り、その他の機能を含むアプリケーション全体で私と一緒に機能しています。サーバーに記事を直接投稿するだけでは機能しません-DrupalのWebサイト。サーバーへのユーザー登録時のPOSTリクエストと完全に連携します。
だから友達、これに関する提案はありますか?なぜ記事を投稿するだけでは機能しないのですか?
どうしてそれはPhoneGapからは機能するが、Javaからは機能しないのか。 PhoneGapはアプリをWebコンテナーで実行するため、すでに認証されています。これで、すべての適切なCookieが得られます。 AJAXは同じセッションを共有し、すべてが「正常に機能する」。
ただし、HTTPClientは完全に異なります。まったく新しいHTTPセッションを開始しているため、すべてが正しくなければなりません。
HTTP認証の仕組みに関するいくつかのコメント:
いくつかのHTTP認証方法があり、どれを選択するかはWebサーバーです。先に進む前に、Drupal構成をチェックして、次のことを確認してください。
(Webコンテナには、サーバーからの要求に応じて、すべての舞台裏でさまざまな認証方法を試すことができる「スマート」があることにも注意してください)
Drupal Webログも確認してください。いくつかの指針:
これが役立つかどうか教えてください。そうでない場合、そしてあなたがこの投稿に従ってより多くの詳細を与えることができるならば、私はより多くのアドバイスでフォローアップすることができます。
同じ「DefaultRequestDirector:認証エラー:これらの課題のいずれにも応答できません:{}」に遭遇しましたDrupalサービスを使用した loopj Android-async-httpライブラリ) (強くお勧めします)。
私にとっての解決策の鍵は、DrupalからのJSON出力に特別な注意を払うことに関する回答の1つにあるJose LUgiaのコメントにありました。 JSONObjectをキャッチしようとしましたが、実際のメッセージは配列形式「["間違ったユーザー名またはパスワード。"]」でした。 JSONArrayに切り替えると、エラーが適切に検出され、処理できるようになりました。あなたの場合、drupalサービスが期待しているように、ログイン資格情報を投稿していないためだと思います。
Drupalサービスでは、システム/接続を実行してセッションを取得し、次にユーザー/ログイン(およびパラメーターとして渡されたユーザー/パスワード)を実行し、セッションを取得してから、すべての後続のリクエストは機能するはずです。これが、これらすべてのリクエストをより管理しやすくするため、loopjライブラリを使用するのが好きな理由です。これは、loopjでdrupalに接続する非常に基本的な例です。後続のすべての投稿は簡単です。 paramsを使用して行われます。
public class Loopj {
private static final String TAG = "loopj";
private static AsyncHttpClient client = new AsyncHttpClient();
private final PersistentCookieStore myCookieStore;
public Loopj(Context context) {
myCookieStore = new PersistentCookieStore(context);
client.setCookieStore(myCookieStore);
client.addHeader("Content-type", "application/json");
}
public void systemConnect(String uri) throws JSONException {
client.post(uri + "/endpoint/system/connect", new JsonHttpResponseHandler() {
@Override
public void onSuccess(JSONObject json) {
Log.i("TAG", "Connect success =" + json.toString());
}
@Override
public void onFailure(Throwable e, String response) {
Log.e("TAG", "Connect failure");
}
});
}
public void userLogin(String uri) throws JSONException {
RequestParams params = new RequestParams();
params.put("username", username);
params.put("password", password);
client.post(uri + "/endpoint/user/login", params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(JSONArray response) {
Log.i("TAG", "Login success =" + response.toString());
}
@Override
public void onFailure(Throwable e, JSONArray json) {
Log.e("TAG", "Login failure");
}
});
}
最初にPHPサイドアウトアプリをテストすることをお勧めします。ヘッダーや認証など、独自の呼び出しを行う方法はいくつかあります。curlからGraphicalHttpClient(http://iTunes.Apple。 com/us/app/graphicalhttpclient/id433095876?mt = 12、私は個人的にそれを使用し、それはきちんと動作します)RESTクライアントデバッガー(https://addons.mozilla。 org/en-US/firefox/addon/restclient /)
このようにして、クライアントで直接行うのが面倒な非常に多くの方法で呼び出しをテストできるようになります(httpからhttpsに変更するか、Authorizationヘッダーにトークンのタイプを追加するだけで、作成がはるかに簡単になる場合があります) n the fly)。
すべてが期待どおりに機能したら、クライアントで同じ呼び出し、ヘッダー、および本文を再現し、準備が整います。
次のことを確認してみてください。 Web認証でApache httpclientを使用してhttp postを実行するにはどうすればよいですか?
必要に応じて、HttpInterceptor
を使用して認証データを挿入します