0

Context: I have a login form in a SPA that makes an AJAX call to a Silex-PHP API. If the credentials are right, everything works smooth. If the credentials are wrong, the server returns a 401 Unauthorized, and Firefox/Chrome shows the default login form.

I went through this and this questions to try to avoid the browser from prompting.

One of the suggested solutions is to set the WWW-Authenticate header in the response to something different than Basic. Which I did in my Silex API with:

$response->headers->set('WWW-Authenticate', 'FormBased');

When making a request via Postman it shows is working:

Cache-Control → no-cache
Connection → Keep-Alive
Content-Type → application/json
Date → Fri, 30 Jan 2015 19:13:49 GMT
Keep-Alive → timeout=5, max=100
Server → Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8      
PHP/5.6.2 mod_ssl/2.2.29 OpenSSL/0.9.8y DAV/2 mod_perl/2.0.8 Perl/v5.20.0
Transfer-Encoding → chunked
WWW-Authenticate → FormBased <------------------------
X-Powered-By → PHP/5.6.2 

However, when doing the request via AJAX from the browser, the response looks like:

Cache-Control   no-cache
Connection  Keep-Alive
Content-Type    text/html; charset=UTF-8
Date    Fri, 30 Jan 2015 19:03:11 GMT
Keep-Alive  timeout=5, max=74
Server  Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8       
PHP/5.6.2 mod_ssl/2.2.29 OpenSSL/0.9.8y DAV/2 mod_perl/2.0.8 Perl/v5.20.0
Transfer-Encoding   chunked
WWW-Authenticate    Basic realm="Secured"  <------------------------
X-Powered-By    PHP/5.6.2

WWW-Authenticate and Content-Type are different in the responses to the same request.

The AJAX Call is:

$.ajax({
    url:url,
    type:'GET',
    dataType:"json",
    contentType: "application/json",
    headers: { 'PHP_AUTH_USER' : formValues.username, 'PHP_AUTH_PW' : formValues.password },
    success:function (data) {
         console.log(["Login request details: ", data]);

         if(data.error) {  // If there is an error, show the error messages
              console.log('error data');
         }
         else { // If not, send them back to the home page
              App.trigger("home:show");
         }
    },
    error:function(){
         console.log('error logging in');
    },
    statusCode: {
         401: function(){
               console.log('401 invalid credentials');
         }
    }
});

How can the responses be different? How can I drop or override the WWW-Authenticate header in the response for the browsers?

Community
  • 1
  • 1
mezod
  • 2,313
  • 3
  • 21
  • 31
  • 1
    Check Content-Type request header. It's different. – Phil Jan 30 '15 at 20:09
  • true, let me look into that, – mezod Jan 30 '15 at 20:18
  • these are Response headers, not request. However, you are right, the response should be application/json. I'm more confused now, both are requesting to the same endpoint, and in the backend I am setting: 'Content-Type' => 'application/json' – mezod Jan 30 '15 at 20:25
  • Ah yes of course. An unexpected content-type response could be a sign of a bad content-type request. So it's probably a bug in your ajaxing code. – Phil Jan 30 '15 at 20:37
  • i added my ajax call in case you can see something wrong – mezod Jan 30 '15 at 21:37
  • OK it looks fine. I was thinking maybe your dataType was not set. – Phil Jan 30 '15 at 22:08
  • if you have any further ideas on what to try, i'll appreciate em, I am pretty stuck atm :P – mezod Jan 30 '15 at 22:12
  • I would use firebug to check ajax request headers are correct. If request is the same, response should be the same. – Phil Jan 30 '15 at 22:47
  • can't see the entirety of the postman request but it seems to match, and the postman request is the one who gets the proper response – mezod Jan 31 '15 at 01:13

1 Answers1

0

This is a related question and how I finally solved the problem:

How to overwrite a class from the Security Component?

Community
  • 1
  • 1
mezod
  • 2,313
  • 3
  • 21
  • 31