iOS: l'Authentification à l'aide de XMLHttpRequest - Manipulation réponse 401
Je suis en train d'écrire une application iOS à l'aide de PhoneGap (aka Cordoue), j'ai un simple code html de la page de login qui connecte l'utilisateur à l'aide d'un XMLHttpRequest avec l'authentification de base sur le protocole SSL. Tout fonctionne à merveille lorsque vous entrez votre nom d'utilisateur et le mot de passe correctement. Toutefois, si vous entrez le mauvais nom d'utilisateur/mot de passe, aucun de mes rappels sont jamais appelés.
Si vous exécutez le même code sur Chrome par exemple, avec le mauvais nom d'utilisateur/mot de passe, chrome se comporte de la même manière, sauf qu'il apparaît une boîte de dialogue de l'authentification. Cliquer sur annuler sur le chrome de la boîte de dialogue renvoie le contrôle de mon code javascript. Malheureusement, sur iOS, la UIWebView l'habitude même apparaître un auth dialogue, il se bloque. J'ai besoin d'un moyen pour indiquer à l'utilisateur qu'ils sont entrés dans le mauvais nom d'utilisateur ou mot de passe afin qu'ils puissent recommencer.
La chose la plus proche à une réponse que j'ai pu trouver ce http://www.freelock.com/2008/06/technical-note-http-auth-with-ajax mais en changeant le statut de la réponse du serveur ne semble pas être la bonne chose à faire.
Ici est ce que ma demande à quoi ressemble le code, mais quand un mauvais nom d'utilisateur ou mot de passe est envoyé, il n'atteint jamais mon rappel onload (en fait la onreadystatechange de rappel ne reçoit appelé une fois et c'est pour readyState 1, aka OUVERT).
var req = new XMLHttpRequest();
req.onload = function(ev) {
if (req.status == 401) {
alert("Invalid Username/Password");
document.getElementById('password').focus();
} else if (req.status == 200) {
window.location.href = some_secure_site;
} else {
//edit //
alert("Some other status");
}
}
req.onerror = function (ev) { alert('Error'); };
req.ontimeout = function(ev) { alert('Timeout'); };
req.open('GET', uri, true, userValue, passValue);
req.withCredentials = true;
req.send();
- Semble être lié à ce problème: issues.apache.org/jira/browse/CB-2415 s'il vous plaît voter pour le faire réparer rapidement
Vous devez vous connecter pour publier un commentaire.
Quelques choses est devenu évident pour moi que d'essayer de le faire sur iOS. L'une est que iOS a un bug relatif à l'authentification basique, donc si votre mot de passe a certains caractères spéciaux, vous ne serez jamais obtenir une réponse de votre serveur parce que votre serveur ne sera jamais une authentification par défi. C'est, si vous utilisez le nom d'utilisateur et le mot de passe dans le champ "ouvrir" la méthode.
Ma conjecture est qu'ils sont en train de faire quelque chose de stupide, comme en l'envoyant http://username:[email protected]/etc quand ils doivent utiliser des en-têtes http et le codage base64 la creds comme
L'autre chose que j'ai apprise, c'est que l'Authentification Basique n'est pas très sûr et est sujette à un million et un des problèmes. Dont l'un qui vous ennuie, c'est que le client en cache le nom d'utilisateur et mot de passe, qui sera écrasé par de nouvelles valeurs que vous envoyez par l'intermédiaire de "req.ouvert(...)". Bonne chance qu'à l'aide de javascript seul, vous aurez à faire un peu de magie dans ObjC pour effacer le cache.
Si vous avez le contrôle sur votre serveur, je vous suggère d'aide jeton d'authentification. Se connecter via le protocole SSL et puis de nous envoyer un courrier avec les données JSON contenant le nom d'utilisateur et mot de passe. Le serveur peut alors envoyer des données JSON avec un jeton d'authentification (essentiellement un tas de caractères aléatoires assez longtemps qu'il ne peut pas toujours être deviné, un UUID fonctionne bien. il est généré par le serveur et ne peut être connu que pour le client et le serveur). Ensuite stocker le jeton et le nom d'utilisateur dans le trousseau de sorte que l'utilisateur n'a pas besoin de saisir leurs creds à chaque fois qu'ils commencent à votre application.
Mon serveur sera toujours renvoyer une réponse 200 mais les données JSON contient les informations nécessaires pour réessayer ou de stocker le jeton d'authentification. En général... basic auth fondamentalement suce.
J'ai juste eu le même problème avec aucun des rappels d'être appelé lors de l'utilisation d'iOS + PhoneGap + jQuery. Si je passe des informations d'identification incorrectes et l'utilisation
alors l'erreur de rappel est appelée avec
{"readyState":0,"status":0,"statusText":"timeout"}
. Dans ce cas, vous devez deviner la véritable erreur HTTP 401.Alternativement, vous pouvez utiliser
et votre erreur rappel obtiendrez quelque chose comme
{"readyState":4,"responseText":"<html>...</html>","status":401,"statusText":"Unauthorized"}
dos.Il y a probablement un autre code d'état HTTP à côté de la
401
et200
codes reçus! Assurez-vous il n'y a vraiment pas d'autre code d'état reçues:J'ai eu le même problème - aucun des rappels sur la demande sont appelés, si les informations d'identification non valides sont passés dans l'.
Ma conjecture est que de l'intérieur, la UIWebView est dit de demander les informations d'identification, mais qui invite est en train d'être supprimées, ce qui conduit à ce bug. Ceci est basé sur tous les autres navigateurs que j'ai essayé (Safari, Chrome, Firefox) en n'appelant pas les rappels dans ce cas jusqu'à ce que après le message est rejeté.
Une autre solution (celle que j'utilise) serait de ne pas utiliser Javascript pour faire de l'authentification, et au lieu de le faire sur iOS côté - vous pouvez utiliser le code sur Comment afficher l'Authentification dans UIWebView? rugueuse comme modèle pour ce faire.
Pour résoudre ce problème, supprimez l'en-tête
WWW-Authenticate
de réponse du serveur.