我目前正在处理AngularJS应用的登录页面问题。登录页面使用$http
服务使用基本身份验证(Authorization: Basic (username and password in base 64)
)将用户名和密码提交给Web服务,该Web服务可能在也可能不在托管webapp的同一服务器上运行。如果验证成功,则服务器返回状态为200 OK的响应;否则,它返回401 Not Authorized。我们有一个错误函数来优雅地处理这个错误条件,但在它被调用之前,浏览器默认显示一个模态对话框供用户输入他或她的用户名和密码。我该如何防止这种情况?
我已经查看了几个来源,包括XHR.send()的W3标准,以获得帮助,我的调查结果表明,在Firefox和Chrome中,401响应XHR调用后弹出浏览器对话框以下是真实的:
1)请求是“同源”(在Web服务在为webapp提供服务的同一服务器上运行的情况下)
2)回复包括标题WWW-Authenticate: Basic [some realm]
或WWW-Authenticate: Digest [some realm]
(我们的网络服务返回前者)
3)请求不是通过在调用send()
方法的XHR对象中专门设置用户名和密码来完成的。
我发现了一个测试网站(SO不会让我链接),它显示了401响应的所需行为(没有模态登录框)。它符合前两个条件,但避免遇到第三个,显然是因为它通过将#4和5作为参数#4和5发送到其open()
函数来设置XHR对象的用户名和密码。我不确定是否有其他方法来设置XHR对象的这些属性,因为我甚至无法通过在浏览器的JavaScript调试器中检查XHR对象来找到它们。
问题是我们网站的登录服务本身不会调用XmlHttpRequest.open()
来传递用户名和密码;相反,它会创建Authorization标头,并将其传递给params对象的headers集合中$http
。通过检查angular.js的来源,我发现$ http然后只用三个参数调用open()
。
Angular是否提供了一种方法让$http
调用open()的5参数重载,否则会阻止此登录对话框显示?如果没有,我只能想到一些解决方法:
1)如果提供了用户名和密码,以某种方式装饰$http
以强制调用open()
的5参数重载
2)以某种方式使用$httpBackend
来实现与#1相同(尽管文档不鼓励开发人员使用$httpBackend
所以我不确定这是一个好主意还是可能)
3)忽略$http
并让我的登录服务创建并发送XHR本身
4)更改服务器,使其不返回WWW-Authenticate: Basic
标题(最不可取)
是否有一种众所周知或“正确”的方法来解决这个问题?
答案 0 :(得分:0)
您面临的问题是由于您指定的第一个原因
1)请求是“同源”(在Web服务在为webapp提供服务的同一服务器上运行的情况下)。
解决方案
将access-control-allow-origin标头添加到后端服务,以便接收来自不同来源的呼叫。
或强>
如果您处于开发阶段,之后您的前端和服务无论如何都是相同的来源,那么请使用https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en扩展名,
这将允许您覆盖chrome cross origin策略(这仅用于开发,它是一种解决方法)。
或
通过从命令提示符
打开chrome来禁用Web安全性,打开Chromechrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security