Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.5k views
in Technique[技术] by (71.8m points)

jquery - Safari Ajax cors request not following redirect

Basically, I have a login form that once authenticated it starts an Oauth2 process. Which works flawlessly until it has to do the final redirect which gets the access tokens. The login flow is as follows POST to /user/login redirects to /user/oauth/auth then redirects to the Oauth redirect_uri /user/oauth/redirect. The redirect_uri never happens and the request never hits the server.

If I hit that redirect using an Ajax request the cors works fine and I get the expected response it only seems to happen if I redirect twice.

The server shows these responses

[I 130226 10:16:38 web:1462] 302 POST /user/login (192.168.1.5) 156.01ms  (Session cookies set fine)
[I 130226 10:16:38 web:1462] 200 OPTIONS /user/oauth/auth?scope=&client_id=DemoApp&response_type=code&redirect_uri=http://192.168.1.5:8443/user/oauth/redirect/code (192.168.1.5) 1.86ms
302 GET /user/oauth/auth?scope=&client_id=DemoApp&response_type=code&redirect_uri=http://192.168.1.5:8443/user/oauth/redirect/code (192.168.1.5) 8.58ms

The last URL never get's hit. In Chrome, IE, FF the flow is the same except the server sees the request

[I 130226 10:16:38 web:1462] 302 POST /user/login (192.168.1.5) 156.01ms  
[I 130226 10:16:38 web:1462] 200 OPTIONS /user/oauth/auth?scope=&client_id=DemoApp&response_type=code&redirect_uri=http://192.168.1.5:8443/user/oauth/redirect/code (192.168.1.5) 1.86ms
302 GET /user/oauth/auth?scope=&client_id=DemoApp&response_type=code&redirect_uri=http://192.168.1.5:8443/user/oauth/redirect/code (192.168.1.5) 8.58ms
[I 130226 10:27:12 web:1462] 200 GET /user/oauth/redirect/code?code=57497058fbbf6003310ea22d3902ac67 (192.168.1.5) 0.54ms

In the Web Inspector I see the request but dies like a

enter image description here

I'm using Jquery 1.9 and here is the ajax request (granted I've got every option under the sun in here to try and make it work.)

$.ajax({
    type: "POST",
    url: reqUrl,
    data: data,
    dataType: "json",
    success: function(data, textStatus) {
            console.log(data);
            alert('logged in');

    },
    error: function(e){
        console.log(e);
    },
    complete: function(request, status) {
        console.log("headers=" + request.getAllResponseHeaders());
    },
    statusCode: {
    200: function(data) {
        console.log('yup we got it.')
    }
  },
  xhrFields: {
    withCredentials: true
  },
  crossDomain: true,
  async:true
});

JSONP is not an option as the initial post is sent over https and has to be a POST request. Again all other browsers including IE are working just fine, it fires the success response.

Safari fires the Statuscode 0 and error which is classic Origin policy errors but that redirect uri works in a standard ajax request bypassing the login. I doubt it's a access-control issue because the call would work if Safari would just fire it.

I'm pretty sure it has something to do with the request headers on the redirect and Safari is stopping the request. On the first successful 302 they look like this

Access-Control-Request-Method: GET
Origin: http://192.168.1.5:9090
Access-Control-Request-Headers: origin, accept-encoding, accept-language

But on the redirect uri they look like this (which makes sense as to why it's failing cause there are no access-control headers being sent but why??)

Origin: http://192.168.1.5:9090
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17
Accept: */*
Referer: http://192.168.1.5:9090/login
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Well it looks like this is a Safari thing, it will only follow the first redirect. Apple claims that this is the way the HTML spec is written. So.... Had to rework my flow to not redirect on /user/login and start the oauth process right away.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...