การโหลด NSURLSession / NSURLConnection HTTP ล้มเหลวใน iOS 9


137

พยายามที่จะใช้ app ที่มีอยู่ของฉันใน iOS9 AFURLSessionManagerแต่ได้รับความล้มเหลวในขณะที่ใช้

__block NSURLSessionDataTask *task = [self.sessionManager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
    if (error) {

    } else {

    }
}];

[task resume];

ฉันได้รับข้อผิดพลาดต่อไปนี้:

Error Domain=NSURLErrorDomain Code=-999 "cancelled.

ยังได้รับบันทึกต่อไปนี้ด้วย:

 NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824
 CFNetwork SSLHandshake failed (-9824)

อัปเดต: ฉันได้เพิ่มการอัปเดตหลายโซลูชันของฉัน: โหลด NSURLSession / NSURLConnection HTTP ล้มเหลวใน iOS 9


คุณแน่ใจหรือว่ามีข้อผิดพลาดเกิดขึ้นในบรรทัดแรก
BSMP

1
ฉันมีปัญหาเดียวกัน สิ่งนี้ดูเหมือนจะครอบคลุมถึงปัญหา: stackoverflow.com/questions/30720813/ …
phillies2628

คำตอบ:


240

ค้นพบวิธีแก้ปัญหา:

ใน iOS9 ATS บังคับใช้แนวปฏิบัติที่ดีที่สุดระหว่างการโทรผ่านเครือข่ายรวมถึงการใช้ HTTPS

จากเอกสารของ Apple:

ATS ป้องกันการเปิดเผยโดยไม่ตั้งใจให้พฤติกรรมเริ่มต้นที่ปลอดภัยและง่ายต่อการปรับใช้ คุณควรปรับใช้ ATS โดยเร็วที่สุดโดยไม่คำนึงว่าคุณกำลังสร้างแอพใหม่หรืออัปเดตแอปที่มีอยู่ หากคุณกำลังพัฒนาแอพใหม่คุณควรใช้ HTTPS โดยเฉพาะ หากคุณมีแอพที่มีอยู่คุณควรใช้ HTTPS ให้มากที่สุดในตอนนี้และสร้างแผนสำหรับการโอนย้ายแอปที่เหลือของคุณโดยเร็วที่สุด

ในรุ่นเบต้า 1 ในขณะนี้ยังไม่มีวิธีการกำหนดใน info.plist โซลูชันคือการเพิ่มด้วยตนเอง:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

ป้อนคำอธิบายรูปภาพที่นี่

Update1: นี่เป็นวิธีแก้ปัญหาชั่วคราวจนกว่าคุณพร้อมที่จะใช้การสนับสนุน ATS iOS9

Update2:สำหรับรายละเอียดเพิ่มเติมโปรดอ้างอิงลิงค์ต่อไปนี้: http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Update3:หากคุณพยายามเชื่อมต่อกับโฮสต์ (YOURHOST.COM) ที่มีเฉพาะ TLS 1.0

เพิ่มสิ่งเหล่านี้ลงใน Info.plist ของแอปของคุณ

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>YOURHOST.COM</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>1.0</string>
            <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

10
โปรดทราบว่าคุณเพิ่งลบ Application Transport Security ออกไปอย่างสมบูรณ์ดังนั้นฟีเจอร์ iOS 9 ที่สำคัญก็หายไปจากแอพของคุณ นี่คือแฮ็คและฉันจะไม่แปลกใจถ้าแฮ็คนั้นจะทำให้แอปของคุณถูกปฏิเสธ การเพิ่มเว็บไซต์เฉพาะลงในพจนานุกรมนี้จะมีโอกาสมากขึ้น
gnasher729

2
@StevenPeterson คุณจะสามารถรับแอปทั้งหมดยกเว้นแอปเปิ้ลเป็นกรณี ๆ ไป ฉันคิดว่าถ้าแอปเปิ้ลอวยพรแอปของคุณด้วยความสามารถนี้พวกเขาจะแนะนำให้คุณใส่รหัสนี้ คาดว่าแอปเปิ้ลจะทำเช่นนี้ไม่ค่อย
mattyohe

8
ได้โปรดได้โปรดได้โปรดได้โปรดอย่าเพิ่งเพิ่มข้อยกเว้นลงในเพลทของคุณและไปที่ "เพียงเพราะมันใช้งานได้" พิจารณาความปลอดภัยของข้อมูลผู้ใช้ของคุณและใช้ SSL และแนวทางปฏิบัติด้านความปลอดภัยอื่น ๆ
ซานตาคลอส

8
@ gnasher729 ฉันเข้าใจดีกว่าที่จะรองรับ TLS 1.2 แทนที่จะปิดใช้งาน ATS อย่างไรก็ตามคุณสามารถทำอะไรได้หากคุณใช้ API / เว็บของบุคคลที่สาม ฉันไม่สามารถบังคับให้พวกเขาอัปเกรดดังนั้นฉันควรทำอย่างไร ??
Woodstock

7
มีข้อผิดพลาดที่ลึกซึ้งในคำตอบนี้คือNSTemporaryExceptionMinimumTLSVersionจะต้องเป็นเช่นTLSv1.0แทน1.0ดู NSAppTransportSecurity โดเมนยกเว้นปุ่มพจนานุกรม
MBI

54

วิธีจัดการกับ SSL ใน iOS9, วิธีแก้ปัญหาอย่างหนึ่งคือ:

อย่างที่Appleพูดว่า: ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

iOS 9 และ OSX 10.11 ต้องใช้ TLSv1.2 SSL สำหรับโฮสต์ทั้งหมดที่คุณวางแผนที่จะขอข้อมูลเว้นแต่คุณจะระบุโดเมนข้อยกเว้นในไฟล์ Info.plist ของแอป

ไวยากรณ์สำหรับการกำหนดค่า Info.plist มีลักษณะดังนี้:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow insecure HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

หากแอปพลิเคชันของคุณ (เช่นเว็บเบราว์เซอร์ของบุคคลที่สาม) จำเป็นต้องเชื่อมต่อกับโฮสต์โดยพลการคุณสามารถกำหนดค่าดังนี้:

<key>NSAppTransportSecurity</key>
<dict>
    <!--Connect to anything (this is probably BAD)-->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

หากคุณต้องทำสิ่งนี้อาจเป็นการดีที่สุดที่จะอัปเดตเซิร์ฟเวอร์ของคุณเพื่อใช้ TLSv1.2 และ SSL หากยังไม่ได้ดำเนินการ นี่ควรเป็นวิธีแก้ปัญหาชั่วคราว

ณ วันนี้เอกสารก่อนวางจำหน่ายไม่ได้กล่าวถึงตัวเลือกการกำหนดค่าเหล่านี้ในลักษณะเฉพาะใด ๆ ฉันจะอัปเดตคำตอบเพื่อเชื่อมโยงไปยังเอกสารที่เกี่ยวข้อง

สำหรับข้อมูลเพิ่มเติมไปที่iOS9AdaptationTips


4
SSL และ TLS เป็นชั้นการเข้ารหัสที่แตกต่างกันที่ใช้โดยโปรโตคอล HTTPS ดังนั้นหนึ่งควรปิดการใช้งาน SSL ทั้งหมดและใช้ TLS v1.2 หรือใหม่กว่า สำหรับข้อมูลเพิ่มเติมฉันขอแนะนำให้เริ่มต้นด้วยทรัพยากรต่อไปนี้: SSL / TLS Security 2015 - คู่มือฉบับย่อแบบง่าย
Conrad Taylor

2
ฉันเพิ่งเพิ่มโชคใด ๆ กับตัวอย่างด้านล่างที่คุณตั้ง NSAllowsArbitraryLoads เป็นจริง เซิร์ฟเวอร์ของฉันใช้ TLS v1.2 โดยเฉพาะและฉันยังต้องทำสิ่งนี้เพื่อให้มันใช้งานได้ น่าผิดหวังมาก
สกูตเตอร์

1
ดังนั้นมีวิธีแก้ปัญหาใดบ้างที่ฉันสามารถใช้เพื่อทราบว่าแอปใหม่ของฉันจะได้รับการอนุมัติใน App Store เช่นบริการพร็อกซี่หรือไม่
Josh

41

แอปเปิ้ล Technote บน App ขนส่งการรักษาความปลอดภัยเป็นประโยชน์มาก ; มันช่วยให้เราค้นหาโซลูชันที่ปลอดภัยยิ่งขึ้นสำหรับปัญหาของเรา

หวังว่านี่จะช่วยคนอื่นได้ เราประสบปัญหาในการเชื่อมต่อกับ Amazon S3 URL ที่ดูเหมือนว่าจะถูกต้องสมบูรณ์แบบ, TLSv12 HTTPS URL ปรากฎว่าเราต้องปิดการใช้งานNSExceptionRequiresForwardSecrecyเพื่อเปิดใช้ ciphers จำนวนหนึ่งที่ S3 ใช้

ในของเราInfo.plist:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>amazonaws.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
  </dict>
</dict>

นี่เป็นปัญหาที่แน่นอนของฉันและแก้ไขได้ทันที! ขอบคุณ! :)
Alex Zak

นี่เป็นการแก้ปัญหาที่ฉันมีเช่นกัน กรณีที่แตกต่างกันอาจต้องใช้การตั้งค่าที่แตกต่างกัน ข่าวดีก็คือเขา technote ยังมีข้อมูลเกี่ยวกับวิธีการใช้ nsurl เพื่อช่วยคุณค้นหาการตั้งค่าที่ถูกต้องโดยทั่วไป
ecotax

ฉันต้องทำแบบเดียวกันกับ cloudfront.net ถ้าฉันใช้ CDN ด้านหน้า Amazon S3
Raymond26

7

หากคุณมีปัญหากับ Amazon S3 ในฐานะฉันลองวางสิ่งนี้ลงบน info.plist ในฐานะลูกโดยตรงของแท็กระดับบนสุดของคุณ

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>amazonaws.com</key>
        <dict>
              <key>NSThirdPartyExceptionMinimumTLSVersion</key>
              <string>TLSv1.0</string>
              <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
              <false/>
              <key>NSIncludesSubdomains</key>
              <true/>
        </dict>
        <key>amazonaws.com.cn</key>
        <dict>
              <key>NSThirdPartyExceptionMinimumTLSVersion</key>
              <string>TLSv1.0</string>
              <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
              <false/>
              <key>NSIncludesSubdomains</key>
              <true/>
        </dict>
    </dict>
</dict>

คุณสามารถหาข้อมูลเพิ่มเติมได้ที่:

http://docs.aws.amazon.com/mobile/sdkforios/developerguide/ats.html#resolving-the-issue


2
ขอให้พระเจ้าคุ้มครองคุณ
Vervatovskis

5

ฉันพบทางออกจากที่นี่ และมันก็ใช้ได้สำหรับฉัน

ตรวจสอบสิ่งนี้มันอาจช่วยคุณได้

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
         <dict>
             <key>myDomain.com</key>
                    <dict>
                      <!--Include to allow subdomains-->
                      <key>NSIncludesSubdomains</key>
                      <true/>
                      <!--Include to allow HTTP requests-->
                      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                      <true/>
                      <!--Include to specify minimum TLS version-->
                      <key>NSTemporaryExceptionMinimumTLSVersion</key>
                      <string>TLSv1.1</string>
                </dict>
          </dict>
</dict>

4

เพียงเพิ่มฟิลด์ต่อไปนี้ในไฟล์. plist ของคุณ

ป้อนคำอธิบายรูปภาพที่นี่

ไวยากรณ์มีลักษณะดังนี้:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

สิ่งนี้จะช่วยให้คำขอ http ทั้งหมด ใช้งานได้ แต่ไม่แนะนำ
KVISH

2

ปรับปรุง:

ตั้งแต่ Xcode 7.1 คุณไม่จำเป็นต้องป้อนNSAppTransportSecurityพจนานุกรมด้วยตนเองในinfo.plistพจนานุกรมใน

ตอนนี้มันจะเติมข้อความอัตโนมัติให้คุณรู้ว่ามันเป็นพจนานุกรมแล้วเติมข้อความอัตโนมัติด้วยAllows Arbitraryเช่นกัน ภาพหน้าจอของ info.plist


สิ่งนี้จะช่วยให้คำขอ http ทั้งหมด ใช้งานได้ แต่ไม่แนะนำ
KVISH

2

แก้ไขข้อผิดพลาดโหลด NSURLConnection Http ไม่สำเร็จเพียงเพิ่ม Dict ต่อไปนี้ใน info.plist:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
    </dict>

1

ฉันแก้ไขมันด้วยการเพิ่มคีย์ใน info.plist ขั้นตอนที่ฉันติดตามคือ:

ฉันเปิดไฟล์ info.plist ของโครงการ

เพิ่มรหัสที่เรียกว่า NSAppTransportSecurity เป็นพจนานุกรม

เพิ่มคีย์ย่อยชื่อ NSAllowsArbitraryLoads เป็น Boolean และตั้งค่าเป็น YES เหมือนภาพต่อไปนี้ ป้อนคำอธิบายรูปภาพที่นี่

ทำความสะอาดโครงการและตอนนี้ทุกอย่างทำงานได้ดีเหมือนเมื่อก่อน

ลิงก์อ้างอิง: https://stackoverflow.com/a/32609970


1

นี่คือสิ่งที่ทำงานสำหรับฉันเมื่อฉันมีข้อผิดพลาดนี้:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
        </dict>
    </dict>
</dict>

1

คุณสามารถลองเพิ่มฟังก์ชันนี้ในไฟล์ RCTHTTPRequestHandler.m

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); }


1

นอกจากคำตอบข้างต้นแล้วให้ตรวจสอบ URL ของคุณอีกครั้ง


ในกรณีของฉันฉันพยายามโหลดไฟล์. html
Vaishnavi

0

คุณควรเพิ่มApp Transport Security Settingsการinfo.plistและเพิ่มAllow Arbitrary LoadsการApp Transport Security Settings

ป้อนคำอธิบายรูปภาพที่นี่

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.