javascript - 如何防止浏览器调用基本的auth弹出窗口并使用Jquery处理401错误?

我需要使用基本身份验证发送授权请求。 我已经使用jquery成功实现了这一点。 但是当我得到401错误时,基本的auth浏览器弹出窗口被打开,并且没有调用jquery ajax错误回调。

10个解决方案
40 votes

我最近也面临这个问题。 由于您无法在headers : { "Authorization" : "BasicCustom" } (基本或摘要式身份验证)的情况下更改浏览器显示弹出窗口的默认行为,因此有两种方法可以解决此问题:

  • 将服务器响应更改为不返回headers : { "Authorization" : "BasicCustom" } .返回200代码并在jQuery客户端中处理此代码。
  • 将您用于授权的方法更改为标头中的自定义值。 浏览器将显示Basic和Digest的弹出窗口。 您必须在客户端和服务器上更改此设置。

    headers : {
      "Authorization" : "BasicCustom"
    }
    

还请看一下使用jQuery和Basic Auth的示例。

nwinkler answered 2019-08-13T19:29:49Z
31 votes

返回通用的400状态代码,然后处理该客户端。

或者您可以保留401,而不是返回WWW-Authenticate标头,这正是浏览器通过身份验证弹出窗口响应的内容。 如果缺少WWW-Authenticate标头,则浏览器不会提示输入凭据。

Ibraheem answered 2019-08-13T19:30:22Z
17 votes

您可以使用请求网址抑制基本身份验证弹出窗口,如下所示:

https://username:password@example.com/admin/...

如果您收到401错误(用户名或密码错误),将使用jquery错误回调正确处理。 它可能会导致一些安全问题(如果是http协议而不是https),但它可以正常工作。

UPD:此解决方案支持将在Chrome 59中删除

Ivan Samovar answered 2019-08-13T19:31:00Z
9 votes

正如其他人所指出的,改变浏览器行为的唯一方法是确保响应不包含401状态代码,或者如果包含,则不包括WWW-Authenticate: Basic标头。 由于更改状态代码不是非常语义和不可取的,因此一种好的方法是删除标头WWW-Authenticate。 如果您不想或不想修改您的Web服务器应用程序,您始终可以通过Apache提供服务或代理它(如果您尚未使用Apache)。

以下是Apache重写响应以删除WWW-Authenticate头的配置请求包含的IFF包含头mod_headers(默认情况下由JQuery / AngularJS等主要Javascript框架设置等)并且响应包含 标题sudo a2enmod headers

在Apache 2.4上测试(不确定它是否适用于2.2)。这取决于安装的mod_headers模块。(在Debian / Ubuntu上,sudo a2enmod headers并重启Apache)

    <Location />
            # Make sure that if it is an XHR request,
            # we don't send back basic authentication header.
            # This is to prevent the browser from displaying a basic auth login dialog.
            Header unset WWW-Authenticate "expr=req('X-Requested-With') == 'XMLHttpRequest' && resp('WWW-Authenticate') =~ /^Basic/"
    </Location>   
syastrov answered 2019-08-13T19:31:43Z
4 votes

如果您正在使用IIS服务器,则可以设置IIS URL重写(v2)以在请求的URL上将response_www_authenticate标头重写为None

在这里指导。

您要更改的值是response_www_authenticate

如果您需要更多信息,请添加评论,我将发布web.config文件。

Zymotik answered 2019-08-13T19:32:28Z
3 votes

使用X-Requested-With:XMLHttpRequest和您的请求标头。因此响应头不包含WWW-Authenticate:Basic。

beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', ("Basic "
                        .concat(btoa(key))));
                    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                },
sedhu answered 2019-08-13T19:32:55Z
2 votes

或者,如果您可以自定义服务器响应,则可以返回403 Forbidden。

浏览器不会打开身份验证弹出窗口,将调用jquery回调。

Javier Ferrero answered 2019-08-13T19:33:27Z
2 votes

如果删除了WWW-Authenticate标头,那么您将无法获得凭据的缓存,并且不会在请求中返回Authorization标头。 这意味着现在您必须为您生成的每个新请求输入凭据。

user2491441 answered 2019-08-13T19:33:52Z
1 votes

在Safari中,您可以使用同步请求来避免浏览器显示弹出窗口。 当然,同步请求只应在这种情况下用于检查用户凭据...您可以在发送实际请求之前使用此类请求,如果内容(发送或接收)非常繁重,可能会导致糟糕的用户体验。

    var xmlhttp=new XMLHttpRequest;
    xmlhttp.withCredentials=true;
    xmlhttp.open("POST",<YOUR UR>,false,username,password);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
Emmanuel Sellier answered 2019-08-13T19:34:20Z
0 votes

创建/登录网址,而不是接受&#34;用户&#34; 和#34;密码&#34; 通过GET参数并且不需要基本身份验证。 在这里,使用php,node,java,whatever和解析你的passwd文件并匹配参数(user / pass)。 如果匹配则重定向到[http:// user:pass@domain.com/](这将在您的浏览器上设置凭据)如果没有,则发送401响应(没有WWW-Authenticate标头)。

neiker answered 2019-08-13T19:34:47Z
translate from https://stackoverflow.com:/questions/9859627/how-to-prevent-browser-to-invoke-basic-auth-popup-and-handle-401-error-using-jqu