gpt4 book ai didi

javascript - iOS:使用 XMLHttpRequest 进行身份验证 - 处理 401 响应

转载 作者:技术小花猫 更新时间:2023-10-29 11:06:05 24 4
gpt4 key购买 nike

我正在使用 PhoneGap(又名 Cordova)编写一个 iOS 应用程序,我有一个简单的 html 登录页面,该页面使用 XMLHttpRequest 和基于 SSL 的基本身份验证来记录用户。当您正确输入用户名和密码时,一切都会正常运行。但是,如果您输入了错误的用户名/密码,我的任何回调都不会被调用。

例如,如果您在 Chrome 上运行相同的代码,使用错误的用户名/密码,Chrome 会以类似的方式运行,只是它会弹出身份验证质询对话框。在 chrome 的对话框上点击取消会将控制权返回给我的 javascript 代码。不幸的是,在 iOS 上,UIWebView 甚至不会弹出身份验证对话框,它只是挂起。我需要一种方法来告诉用户他们输入了错误的用户名或密码,以便他们重试。

我能找到的最接近答案的是这个 http://www.freelock.com/2008/06/technical-note-http-auth-with-ajax但是从服务器更改响应状态似乎不是正确的做法。

这基本上是我的请求代码的样子,但是当发送错误的用户名或密码时,它永远不会到达我的 onload 回调(实际上 onreadystatechange 回调只被调用一次,那是 readyState 1,又名 OPEN)。

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();

最佳答案

尝试在 iOS 上执行此操作时,我发现了一些事情。一个是 iOS 有一个与基本身份验证相关的错误,因此如果您的密码中包含某些特殊字符,您将永远不会从服务器收到响应,因为您的服务器永远不会收到身份验证质询。也就是说,如果您在“打开”方法中使用用户名和密码字段。

我的猜测是他们正在做一些愚蠢的事情,比如通过 http://username:password@myorigin.com/etc 发送它,而他们应该像这样使用 http header 和 base64 编码信用

req.setRequestHeader("Authorization", "Basic " + base64(username) + ':' + base64(password));

我了解到的另一件事是,基本身份验证不是很安全,而且容易出现一百万零一个问题。其中一个会让您烦恼的是客户端将缓存用户名和密码,这将覆盖您通过“req.open(...)”发送的任何新值。祝你好运,单独使用 javascript 解决这个问题,你必须在 ObjC 中做一些魔术来清除缓存。

如果您可以控制您的服务器,我建议您使用 token 身份验证。通过 SSL 连接,然后发送包含用户名和密码的 JSON 数据的 POST。然后服务器可以发送回带有身份验证 token 的 JSON 数据(本质上是一堆随机字符,足够长以至于永远无法猜到,UUID 效果很好。这是由服务器生成的,只能为客户端所知,并且服务器)。然后将 token 和用户名存储在钥匙串(keychain)中,这样用户就不需要在每次启动您的应用程序时都输入他们的凭据。

我的服务器将始终发回 200 响应,但 JSON 数据将包含重试或存储身份验证 token 所需的信息。一般来说...基本身份验证基本上很烂。

try {
var req = new XMLHttpRequest();
req.onload = function(ev) {
var response = JSON.parse(this.responseText);
if (response.success === true) {
// The server will respond with a token that will allow us to login
storeCredentials(userValue, response.token);
// redirect with token
else if (req.status == 401) {
alert("Invalid Username/Password");
document.getElementById('password').focus();
} else {
alert("Some other status");
}
}
req.ontimeout = setTimeout(function(ev) { navigator.notification.alert('Timeout trying to contact the server'); }, 10000);
req.onerror = function(ev) { clearTimeout(this.ontimeout); navigator.notification.alert('Error connecting to the server during authentication.'); };

var uri = myWebOrigin + '/authenticate';
req.open('POST', uri, true);
req.setRequestHeader('Cache-Control', 'no-cache');
req.setRequestHeader('Content-Type', 'application/json');
json_data = {username : Base64.encode(userValue), password : Base64.encode(passValue)};
req.send(JSON.stringify(json_data));
} catch(error) {
navigator.notification.alert('Uh oh, an error occurred trying to login! ' + error);
return;
}

关于javascript - iOS:使用 XMLHttpRequest 进行身份验证 - 处理 401 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11025213/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com