iOS 请求 Instagram Basic Api 失败,响应状态代码:403

iOS ask for Instagram Basic Api Fail, response status code: 403

我已经检查了请求 body 的数据。 Android或者Postman中的这些数据运行都是成功的,而且每次都会用新的代码去询问access_token。但是响应状态代码总是 403 让我很困惑。但是我只是第一次开发 iOS 项目。我想可能是我的 iOS 代码中的某处错误。 这是代码请求 instagram 基本显示 access_token API

func getShortAccessTokenInfo(requestBody: ShortAccessTokenRequestBody,completionHandler: @escaping (ShortAccessTokenResponse) -> Void) {
    
    let url = URL(string: "https://api.instagram.com/oauth/access_token")!
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let encoder = JSONEncoder()
    encoder.keyEncodingStrategy = .convertToSnakeCase
    guard let httpBody = try? encoder.encode(requestBody) else {
        print("Invalid httpBody")
        return
    }
    
    request.httpBody = httpBody
    print("httpBody \(httpBody) ")
    
    URLSession.shared.dataTask(with: request) {
        data, response, error in
        if let data = data {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            do {
                let response = try decoder.decode(ShortAccessTokenResponse.self, from: data)
                completionHandler(response)
            } catch {
                let httpResponse = response as! HTTPURLResponse
                print("\nhttpResponse.statusCode = \(httpResponse.statusCode)\n")
                print("\nhttpResponse.allHeaderFields = \(httpResponse.allHeaderFields)\n")
                print("\nhttpResponse.description = \(httpResponse.description)\n")

                
                let outputStr  = String(data: data, encoding: String.Encoding.utf8)! as String
                print("data = \(outputStr)")
            }
                        
        } else {
            print("No Data")
        }
    }.resume()
}

数据模型在这里

struct ShortAccessTokenRequestBody: Encodable {
    var clientId: String
    var clientSecret: String
    var code: String
    var grantType: String
    var redirectUri: String
}

struct ShortAccessTokenResponse: Decodable {
    var accessToken : String
    var userId : Int
}

这是日志:

状态码:

httpResponse.statusCode = 403

所有标题字段:

httpResponse.allHeaderFields = [AnyHashable("origin-trial"): AuqWincgAuXeuu3KypEMnrrFEJHySaesyJS3EaIH40zvafzrU0Irhb7+5QwZpOqMZrPTjgvFl7Z5jJgy1dNAcQMAAAB6eyJvcmlnaW4iOiJodHRwczovL2luc3RhZ3JhbS5jb206NDQzIiwiZmVhdHVyZSI6IkNyb3NzT3JpZ2luT3BlbmVyUG9saWN5UmVwb3J0aW5nIiwiZXhwaXJ5IjoxNjEzNDExNjYyLCJpc1N1YmRvbWFpbiI6dHJ1ZX0=, AnyHashable("cross-origin-opener-policy"): same-origin-allow-popups;report-to="coop", AnyHashable("Cache-Control"): private, no-cache, no-store, must-revalidate, AnyHashable("report-to"): {"group": "coep", "max_age": 86400, "endpoints": [{"url": "/security/coep_report/"}]},{"group": "coop", "max_age": 86400, "endpoints": [{"url": "/security/coop_report/"}]}, AnyHashable("content-security-policy"): report-uri https://www.instagram.com/security/csp_report/; default-src 'self' https://www.instagram.com; img-src data: blob: https://.fbcdn.net https://.instagram.com https://.cdninstagram.com https://.facebook.com https://.fbsbx.com https://.giphy.com; font-src data: https://.fbcdn.net https://.instagram.com https://.cdninstagram.com; media-src 'self' blob: https://www.instagram.com https://.cdninstagram.com https://.fbcdn.net; manifest-src 'self' https://www.instagram.com; script-src 'self' https://instagram.com https://www.instagram.com https://.www.instagram.com https://.cdninstagram.com wss://www.instagram.com https://.facebook.com https://.fbcdn.net https://.facebook.net 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' https://.www.instagram.com https://www.instagram.com 'unsafe-inline'; connect-src 'self' https://instagram.com https://www.instagram.com https://.www.instagram.com https://graph.instagram.com https://.graph.instagram.com https://graphql.instagram.com https://.cdninstagram.com https://api.instagram.com https://i.instagram.com https://.i.instagram.com wss://www.instagram.com wss://edge-chat.instagram.com https://.facebook.com https://.fbcdn.net https://.facebook.net chrome-extension://boadgeojelhgndaghljhdicfkmllpafd blob:; worker-src 'self' blob: https://www.instagram.com; frame-src 'self' https://instagram.com https://www.instagram.com https://*.instagram.com https://staticxx.facebook.com https://www.facebook.com https://web.facebook.com https://connect.facebook.net https://m.facebook.com; object-src 'none'; upgrade-insecure-requests, AnyHashable("Content-Length"): 20676, AnyHashable("x-frame-options"): SAMEORIGIN, AnyHashable("Pragma"): no-cache, AnyHashable("cross-origin-embedder-policy-report-only"): require-corp;report-to="coep", AnyHashable("Strict-Transport-Security"): max-age=31536000, AnyHashable("x-content-type-options"): nosniff, AnyHashable("Content-Language"): zh-tw, AnyHashable("x-xss-protection"): 0, AnyHashable("proxy-status"): http_request_error; e_clientaddr="AcKYiNAO8yhMSZJyyEYudvZGWQzL-XB3-zoUHCoHbF8NHNnIr-i2ovQf3F3cMLaZ6NllIZz2Qo5Bgx6eJHw"; e_fb_binaryversion="AcLdEktTbz5wJ21gYaJEitTnDh51fwKoh1TWEJBnCTDeDsuWyGfrhaGoKLWBuytlTD_jNpYGEqTKkjuZHHl7upVezSs6uJlj8ok"; e_upip="AcJJDJlMUJsyHsIAGFauA9kxrXY2wohcrnfn50hqCMIY2ykTyJKp6Yzgq3HMhBdEfDpJdFdON7xvDmFgevxPXHhO4y4f7PITGNIpgvs"; e_proxy="AcJPFaA_DemVAz4l_ZIcLlO6dqLEWUrH1S3qyfM0Psu4Qqzm3d7g1IZeYuFfciVB_2EGkehYmN4GEjA"; e_fb_builduser="AcISyC6CAEhH54reK-ewAmKXLcNC8aeHIx4_8Dz6aY83oAk05yOr1kaVHEqYAN-Jcck"; e_fb_vipaddr="AcInfxChauRQiPpxzGfxHV2lNUNaz0TDhZFUIoS85agFhatn6NyYkeG6swkbzrGDNCmkyZk", http_request_error; e_clientaddr="AcIY794j6DB_pmP2rk4VsK1zivmZkN9gKrGfvjHfleRJNRB91E-eM7XwFHBZCUBY8zxtV5TVCl3bZAUl0ZOyUSNYP7HHQgvSuXGPRxosSOaG"; e_fb_binaryversion="AcITNqtpSK2R5tDP_gcliynnda3OUKCZgzK-Xsb-r4KXoTzmkEkQmC9Nir7f8yfGz50vSf-gAKhLabX9TQoI0dDOI6LlWW4BHaI"; e_upip="AcKdip7JMVCIyHNm4r3n_lc1FxZ8WRKNQWBDBUwsupTD4rNfKXV4LFfbOLVbapi7jcyqgp1OMZev9Mrb-zxwQ2fryGpF7P3D-Q"; e_proxy="AcI1jEPhkHHVfIX0U-99CwCpJd9bHFInKVHw9EqNNgHvgWSlCPPyPZ-hKEHGtNUxph6CrXt8H8drm0RL3DAn"; e_fb_builduser="AcKOj-xkkvFvzA7RHW34q4gu4tq7NuVcT_WRvsQwxdJFoGmDmQGrefnKdcJ7Hpb4KEo"; e_fb_vipaddr="AcKa3V32l88jLiYn7E5uzcjwzVyAsdvUFKuu1lo_qhJx5qKrGr1ffkqtyIr9Pxh8QrmPf1EHN5vZItcLz3j9_s-6lutm2G-44iYcaiE", AnyHashable("Content-Type"): text/html; charset=utf-8, AnyHashable("x-ig-push-state"): c2, AnyHashable("Set-Cookie"): rur="FTW4170045842741660136279:01f7f1716e996e603ddf484bdfbc12a6fad1ff6f56053129280eb54ca5906d3e6cf24459"; Domain=.instagram.com; HttpOnly; Path=/; Secure, AnyHashable("access-control-expose-headers"): X-IG-Set-WWW-Claim, AnyHashable("x-aed"): 46, AnyHashable("Vary"): Accept-Language, Cookie, AnyHashable("x-fb-trip-id"): 19638678, AnyHashable("Expires"): Sat, 01 Jan 2000 00:00:00 GMT, AnyHashable("Alt-Svc"): h3-29=":443"; ma=3600,h3-27=":443"; ma=3600, AnyHashable("x-ig-origin-region"): ftw, AnyHashable("Date"): Tue, 10 Aug 2021 12:57:59 GMT]

描述:

<NSHTTPURLResponse: 0x280a5a6e0> { URL: https://api.instagram.com/oauth/access_token } { Status Code: 403, Headers {
"Alt-Svc" =     (
    "h3-29=\":443\"; ma=3600,h3-27=\":443\"; ma=3600"
);
"Cache-Control" =     (
    "private, no-cache, no-store, must-revalidate"
);
"Content-Language" =     (
    "zh-tw"
);
"Content-Length" =     (
    20676
);
"Content-Type" =     (
    "text/html; charset=utf-8"
);
Date =     (
    "Tue, 10 Aug 2021 12:57:59 GMT"
);
Expires =     (
    "Sat, 01 Jan 2000 00:00:00 GMT"
);
Pragma =     (
    "no-cache"
);
"Set-Cookie" =     (
    "rur=\"FTW\0541700458427\0541660136279:01f7f1716e996e603ddf484bdfbc12a6fad1ff6f56053129280eb54ca5906d3e6cf24459\"; Domain=.instagram.com; HttpOnly; Path=/; Secure"
);
"Strict-Transport-Security" =     (
    "max-age=31536000"
);
Vary =     (
    "Accept-Language, Cookie"
);
"access-control-expose-headers" =     (
    "X-IG-Set-WWW-Claim"
);
"content-security-policy" =     (
    "report-uri https://www.instagram.com/security/csp_report/; default-src 'self' https://www.instagram.com; img-src data: blob: https://*.fbcdn.net https://*.instagram.com https://*.cdninstagram.com https://*.facebook.com https://*.fbsbx.com https://*.giphy.com; font-src data: https://*.fbcdn.net https://*.instagram.com https://*.cdninstagram.com; media-src 'self' blob: https://www.instagram.com https://*.cdninstagram.com https://*.fbcdn.net; manifest-src 'self' https://www.instagram.com; script-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://*.cdninstagram.com wss://www.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' https://*.www.instagram.com https://www.instagram.com 'unsafe-inline'; connect-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://graph.instagram.com https://*.graph.instagram.com https://graphql.instagram.com https://*.cdninstagram.com https://api.instagram.com https://i.instagram.com https://*.i.instagram.com wss://www.instagram.com wss://edge-chat.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net chrome-extension://boadgeojelhgndaghljhdicfkmllpafd blob:; worker-src 'self' blob: https://www.instagram.com; frame-src 'self' https://instagram.com https://www.instagram.com https://*.instagram.com https://staticxx.facebook.com https://www.facebook.com https://web.facebook.com https://connect.facebook.net https://m.facebook.com; object-src 'none'; upgrade-insecure-requests"
);
"cross-origin-embedder-policy-report-only" =     (
    "require-corp;report-to=\"coep\""
);
"cross-origin-opener-policy" =     (
    "same-origin-allow-popups;report-to=\"coop\""
);
"origin-trial" =     (
    "AuqWincgAuXeuu3KypEMnrrFEJHySaesyJS3EaIH40zvafzrU0Irhb7+5QwZpOqMZrPTjgvFl7Z5jJgy1dNAcQMAAAB6eyJvcmlnaW4iOiJodHRwczovL2luc3RhZ3JhbS5jb206NDQzIiwiZmVhdHVyZSI6IkNyb3NzT3JpZ2luT3BlbmVyUG9saWN5UmVwb3J0aW5nIiwiZXhwaXJ5IjoxNjEzNDExNjYyLCJpc1N1YmRvbWFpbiI6dHJ1ZX0="
);
"proxy-status" =     (
    "http_request_error; e_clientaddr=\"AcKYiNAO8yhMSZJyyEYudvZGWQzL-XB3-zoUHCoHbF8NHNnIr-i2ovQf3F3cMLaZ6NllIZz2Qo5Bgx6eJHw\"; e_fb_binaryversion=\"AcLdEktTbz5wJ21gYaJEitTnDh51fwKoh1TWEJBnCTDeDsuWyGfrhaGoKLWBuytlTD_jNpYGEqTKkjuZHHl7upVezSs6uJlj8ok\"; e_upip=\"AcJJDJlMUJsyHsIAGFauA9kxrXY2wohcrnfn50hqCMIY2ykTyJKp6Yzgq3HMhBdEfDpJdFdON7xvDmFgevxPXHhO4y4f7PITGNIpgvs\"; e_proxy=\"AcJPFaA_DemVAz4l_ZIcLlO6dqLEWUrH1S3qyfM0Psu4Qqzm3d7g1IZeYuFfciVB_2EGkehYmN4GEjA\"; e_fb_builduser=\"AcISyC6CAEhH54reK-ewAmKXLcNC8aeHIx4_8Dz6aY83oAk05yOr1kaVHEqYAN-Jcck\"; e_fb_vipaddr=\"AcInfxChauRQiPpxzGfxHV2lNUNaz0TDhZFUIoS85agFhatn6NyYkeG6swkbzrGDNCmkyZk\", http_request_error; e_clientaddr=\"AcIY794j6DB_pmP2rk4VsK1zivmZkN9gKrGfvjHfleRJNRB91E-eM7XwFHBZCUBY8zxtV5TVCl3bZAUl0ZOyUSNYP7HHQgvSuXGPRxosSOaG\"; e_fb_binaryversion=\"AcITNqtpSK2R5tDP_gcliynnda3OUKCZgzK-Xsb-r4KXoTzmkEkQmC9Nir7f8yfGz50vSf-gAKhLabX9TQoI0dDOI6LlWW4BHaI\"; e_upip=\"AcKdip7JMVCIyHNm4r3n_lc1FxZ8WRKNQWBDBUwsupTD4rNfKXV4LFfbOLVbapi7jcyqgp1OMZev9Mrb-zxwQ2fryGpF7P3D-Q\"; e_proxy=\"AcI1jEPhkHHVfIX0U-99CwCpJd9bHFInKVHw9EqNNgHvgWSlCPPyPZ-hKEHGtNUxph6CrXt8H8drm0RL3DAn\"; e_fb_builduser=\"AcKOj-xkkvFvzA7RHW34q4gu4tq7NuVcT_WRvsQwxdJFoGmDmQGrefnKdcJ7Hpb4KEo\"; e_fb_vipaddr=\"AcKa3V32l88jLiYn7E5uzcjwzVyAsdvUFKuu1lo_qhJx5qKrGr1ffkqtyIr9Pxh8QrmPf1EHN5vZItcLz3j9_s-6lutm2G-44iYcaiE\""
);
"report-to" =     (
    "{\"group\": \"coep\", \"max_age\": 86400, \"endpoints\": [{\"url\": \"/security/coep_report/\"}]},{\"group\": \"coop\", \"max_age\": 86400, \"endpoints\": [{\"url\": \"/security/coop_report/\"}]}"
);
"x-aed" =     (
    46
);
"x-content-type-options" =     (
    nosniff
);
"x-fb-trip-id" =     (
    19638678
);
"x-frame-options" =     (
    SAMEORIGIN
);
"x-ig-origin-region" =     (
    ftw
);
"x-ig-push-state" =     (
    c2
);
"x-xss-protection" =     (
    0
);

} }

数据:

data = <!DOCTYPE html>
<html lang="zh-tw" class="no-js logged-in ">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

        <title>
                  查無此頁 &bull; Instagram
                </title>

        
        <meta name="robots" content="noimageindex, noarchive">
        <meta name="apple-mobile-web-app-status-bar-style" content="default">
        <meta name="mobile-web-app-capable" content="yes">
        <meta name="theme-color" content="#ffffff">
        <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover">
        <link rel="manifest" href="/data/manifest.json">

        
        
        

        <script type="text/javascript">
        (function() {
  var docElement = document.documentElement;
  var classRE = new RegExp('(^|\s)no-js(\s|$)');
  var className = docElement.className;
  docElement.className = className.replace(classRE, 'js');
})();
</script>
        <script type="text/javascript">
(function() {
  if ('PerformanceObserver' in window && 'PerformancePaintTiming' in window) {
    window.__bufferedPerformance = [];
    var ob = new PerformanceObserver(function(e) {
      window.__bufferedPerformance.push.apply(window.__bufferedPerformance,e.getEntries());
    });
    ob.observe({entryTypes:['paint']});
  }

  window.__bufferedErrors = [];
  window.onerror = function(message, url, line, column, error) {
    window.__bufferedErrors.push({
      message: message,
      url: url,
      line: line,
      column: column,
      error: error
    });
    return false;
  };
  window.__initialData = {
    pending: true,
    waiting: []
  };
  function asyncFetchSharedData(extra) {
    var sharedDataReq = new XMLHttpRequest();
    sharedDataReq.onreadystatechange = function() {
          if (sharedDataReq.readyState === 4) {
            if(sharedDataReq.status === 200){
              var sharedData = JSON.parse(sharedDataReq.responseText);
              window.__initialDataLoaded(sharedData, extra);
            }
          }
        }
    sharedDataReq.open('GET', '/data/shared_data/', true);
    sharedDataReq.send(null);
  }
  function notifyLoaded(item, data) {
    item.pending = false;
    item.data = data;
    for (var i = 0;i < item.waiting.length; ++i) {
      item.waiting[i].resolve(item.data);
    }
    item.waiting = [];
  }
  function notifyError(item, msg) {
    item.pending = false;
    item.error = new Error(msg);
    for (var i = 0;i < item.waiting.length; ++i) {
      item.waiting[i].reject(item.error);
    }
    item.waiting = [];
  }
  window.__initialDataLoaded = function(initialData, extraData) {
    if (extraData) {
      for (var key in extraData) {
        initialData[key] = extraData[key];
      }
    }
    notifyLoaded(window.__initialData, initialData);
  };
  window.__initialDataError = function(msg) {
    notifyError(window.__initialData, msg);
  };
  window.__additionalData = {};
  window.__pendingAdditionalData = function(paths) {
    for (var i = 0;i < paths.length; ++i) {
      window.__additionalData[paths[i]] = {
        pending: true,
        waiting: []
      };
    }
  };
  window.__additionalDataLoaded = function(path, data) {
    if (path in window.__additionalData) {
      notifyLoaded(window.__additionalData[path], data);
    } else {
      console.error('Unexpected additional data loaded "' + path + '"');
    }
  };
  window.__additionalDataError = function(path, msg) {
    if (path in window.__additionalData) {
      notifyError(window.__additionalData[path], msg);
    } else {
      console.error('Unexpected additional data encountered an error "' + path + '": ' + msg);
    }
  };
  
})();
</script><script type="text/javascript">

好的,我已经解决了同样的问题。似乎如果你用 cookie 向 Instagram 的 API 发送请求 ,它会 return 403 返回。在iOS中,URLRequest默认会由系统添加一些cookie,这就导致了这个403问题。

您需要做的是添加:

request.httpShouldHandleCookies = false

针对您关于禁用系统自动添加 cookie 的请求。