上下文
我有一个朋友,他的名字叫鲍勃。
Bob有一台运行应用程序的服务器&只能在本地访问 。为了从外部世界访问这个应用程序,Bob安装了&使用nginx和模块 auth_basic 配置反向代理。
每个请求都通过反向代理进行身份验证过程。两种情况:
一切正常,直到这里。这与基本身份验证规范的预期相似。
问题
鲍勃不喜欢浏览器中的默认对话框,想要一个带有表单的漂亮的html页面。他将nginx服务器配置为拥有自己的html表单。问题是,默认情况下,表单的HTML提交流程不会发送授权标头参数。 Bob需要使用 XMLHttpRequest 。当凭据良好时,他实现它并从服务器接收良好的 200 HTTP响应。
与默认表单行为不同,使用XMLHttpRequest,浏览器在成功的情况下不会自动缓存凭据。因此,每个子请求再次显示登录表单:'(
Bob无法更改本地应用程序的前端代码,以便自己发送每个请求中的凭据(与SPA一样)。实际上,他无法访问此应用。他只能访问nginx conf和他自己的html登录表单。所以存储在这里没用。
问题
bob是否可以在收到XHR响应后让浏览器缓存凭据?
(即使他使用XMLHttpRequest,目标也是默认行为)
编辑:
进一步说明
本地应用程序在localhost上运行。鲍勃没有开发这个应用程序,他无法编辑它。此应用程序不提供身份验证,Bob使用nginx的basic_auth模块作为反向代理来验证人员。
它运行良好,但使用实现Basic Auth规范的浏览器的默认行为。此行为显示丑陋的表单并在成功时缓存凭据。如果Bob提供自己的表单行为go,这是正常的,因为Basic Auth规范需要HTML表单无法提供的特定标头参数(授权:基本...)。 Bob需要使用XHR来提供此参数。
问题是,如何用XHR取回浏览器的良好行为?
我们只能在login.html上使用JS,而不能在本地应用上使用。这是工作流程:
我还准确地说,一个解决方案是用真正的后端应用程序替换nginx基本auth反向代理和另一个身份验证系统(例如自动发送的cookie),它可以作为反向代理但不是问题问。
编辑2:
为什么Bob无法使用存储解决方案?
在ulgy表单场景中,他没有HTML登录文件。当浏览器客户端向服务器请求请求时,服务器仅响应具有 WWW-Authenticate 标头但没有HTML内容的HTTP响应。让此标头参数显示表单的简单事实。只需输入好的凭据就会发回200 HTTP响应,浏览器将缓存凭据并使用HTTP标头授权:基本在每个请求中发送它。
在login.html方案中,成功登录后,我们需要在每个请求中发回HTTP标头授权:基本(不是Cookie,因为它是' s如何工作Basic Auth spec和Bob没有任何后端,只有nginx模块)。可以从login.html发送此标头,因为我们可以在其上附加JS。但是,服务器响应的下一页将是来自本地应用程序的HTML文件,其中Bob无法访问其HTML并且无法在其上附加JS以提供标题授权:基本用于下一个请求。可以从login.html文件中存储cookie,但需要从其他页面检索此cookie并用于发送标题授权:基本,这是不可能的,因为Bob没有访问这些页面的JS。
提前谢谢。
答案 0 :(得分:0)
由于您已经在使用ajax,因此只需设置javascript并读取cookie:
(我在这里使用jQuery,为简单起见,如果你不使用jQuery,用适当的语法替换ajax调用):
function getCookie(cookiename) {
/* a function to find a cookie based on its name */
var r = document.cookie.match('\\b' + cookiename + "=([^;]*)\\b");
// document.cookie returns all cookies for this url
return r ? r[1] : undefined;
// return the regex capture if it has content, otherwise return undefined
}
function getData(auth_basic) {
$.ajax({
url: 'url_of_nginx...',
headers: {
'Authorization': 'Basic ' + auth_basic
} // send auth header on xmlhttprequest GET
}).next(function ajaxSuccess(data) {
// data from the nginx
document.cookie = '_auth_cookie=' + auth_basic;
// store my auth in a cookie
}, function ajaxFailed(jqXHR) {
// do something on failure, like
showLoginForm()
});
}
function showLoginForm() {
/* function to render your form */
// attach an event handler to form submission
$('#submit_button_id').click(function form_submitted(login_evt) {
// I clicked login
login_evt.preventDefault(); // don't really submit the form
// get my field form values
username = $('#username_input_field').val();
password = $('#password_input_field').val();
// I base64 the auth string
var auth_basic = btoa(username + ':' + password);
// try to auth
getData(auth_basic);
});
}
var auth_cookie = getCookie('_auth_cookie');
if (auth_cookie === undefined) {
// I have no cookie
showLoginForm()
} else {
getData(auth_cookie)
}