【问题标题】:How to Make Apollo Client iOS Accept Self-Signed Certificates如何让 Apollo Client iOS 接受自签名证书
【发布时间】:2021-05-07 20:23:09
【问题描述】:

如何让 ApolloClient 接受自签名证书?我们将它用于内部应用程序,并且由于认证问题,对 GraphQL 端点的调用失败。我在存储库问题中找到了this thread,但自那次讨论以来,API 似乎发生了一些变化,而当前正确的方法正在躲避我。

目前,我的集成测试下降到.failure 分支报告证书验证问题:

        let apollo = AppConstants.current.apollo
        apollo.fetch( query: DriverStatementsIncompleteQuery( onepass: "test-user" ) ) { result in
            switch result {
            case .success( let results ):
                print( results )
                XCTAssertNil( results.errors )
                self.completedExpectation.fulfill()
            case .failure( let error ):
                XCTFail( error.localizedDescription )
                self.completedExpectation.fulfill()
            }
        }
        wait( for: [self.completedExpectation], timeout: 5 )

【问题讨论】:

    标签: apollo-ios


    【解决方案1】:

    Apollo iOS 团队的 Ellen Shapiro 非常友好地为我指明了正确的方向。这是我最终得到的结果:

    public struct PromiscuousApolloClientFactory {
        /// Creates an `ApolloClient` instance that is configured to work with certificates that the
        /// OS would otherwise deem invalid, like those that are self-signed.
        /// - Parameter endpointURL: The URL of the GraphQL endpoint.
        /// - Returns: The configured `ApolloClient` instance.
        public static func make( with endpointURL: URL ) -> ApolloClient {
            let store = ApolloStore( cache: InMemoryNormalizedCache() )
            let sessionConfig = URLSessionConfiguration.default
            let client = PromiscuousURLSessionClient( sessionConfiguration: sessionConfig )
            let provider = LegacyInterceptorProvider( client: client, store: store )
            let transport = RequestChainNetworkTransport( interceptorProvider: provider, endpointURL: endpointURL )
            
            return ApolloClient( networkTransport: transport, store: store )
        }
    }
    
    private class PromiscuousURLSessionClient: URLSessionClient {
        override func urlSession( _ session: URLSession,
                                  didReceive challenge: URLAuthenticationChallenge,
                                  completionHandler: @escaping ( URLSession.AuthChallengeDisposition, URLCredential? ) -> Void ) {
            let protectionSpace = challenge.protectionSpace
            
            guard protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
                  let serverTrust = protectionSpace.serverTrust else {
                    completionHandler( .performDefaultHandling, nil )
                    return
            }
            
            let credential = URLCredential( trust: serverTrust )
            completionHandler( .useCredential, credential )
        }
    }
    

    注意事项:这通常是一种不好的做法,因为它会为您自己的利益而短路安全保护。如果您有使用操作系统可以验证的证书的路径,请改为这样做。 :)

    【讨论】:

      猜你喜欢
      • 2022-10-17
      • 2019-12-23
      • 2021-03-30
      • 1970-01-01
      • 2015-12-25
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多