如何在Apollo GraphQL中添加标题:iOS

Ang*_*rus 1 ios apollo graphql apollo-client

Hy我正在一个有Apollo GraphQL方法的项目,它的工作正常。但是现在客户端需要使用Apollo API添加其他标头。但是添加标头后,API的响应将返回unAuthorized

我将标题添加为

    let apolloAuth: ApolloClient = {
        let configuration = URLSessionConfiguration.default

        // Add additional headers as needed
        configuration.httpAdditionalHeaders = ["Authorization" : self.singleTonInstance.token]
        configuration.httpAdditionalHeaders = ["channel" : "mobile"]

        let url = URL(string: "http://xxx/graphql")!

        return ApolloClient(networkTransport: HTTPNetworkTransport(url: url, configuration: configuration))

    }()
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我了解如何使用Apollo GraphQL添加标头。

Ger*_*gen 9

从 Apollo Client v0.34.0 及更高版本开始,之前提供的代码将无法工作,因为他们重写了以前的工作方式。这是对我有用的方法...有关更多信息,请考虑通过此处的链接浏览此文档。

class Network {
  static let shared = Network()
  
    private(set) lazy var apollo: ApolloClient = {
        let client = URLSessionClient()
        let cache = InMemoryNormalizedCache()
        let store = ApolloStore(cache: cache)
        let provider = NetworkInterceptorProvider(client: client, store: store)
        let url = URL(string: "https://www.graphqlapi.com/")!
        let transport = RequestChainNetworkTransport(interceptorProvider: provider,
                                                     endpointURL: url)
        return ApolloClient(networkTransport: transport)
    }()
}

class NetworkInterceptorProvider: LegacyInterceptorProvider {
    override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
        var interceptors = super.interceptors(for: operation)
        interceptors.insert(CustomInterceptor(), at: 0)
        return interceptors
    }
}

class CustomInterceptor: ApolloInterceptor {
    // Find a better way to store your token this is just an example
    let token = "YOUR TOKEN"
    
    func interceptAsync<Operation: GraphQLOperation>(
        chain: RequestChain,
        request: HTTPRequest<Operation>,
        response: HTTPResponse<Operation>?,
        completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void) {
        
        request.addHeader(name: "authorization", value: "Bearer: \(token)")

        chain.proceedAsync(request: request,
                           response: response,
                           completion: completion)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 多么噩梦的 API!`NetworkInterceptorProvider:旧版InterceptorProvider`! (2认同)

Cha*_*van 8

更新:“Apollo Client v0.41.0”和“Swift 5”的解决方案

我在 Apollo Client v0.41.0 和 Swift 5.0 上遇到了同样的问题,但上述解决方案都没有奏效。经过数小时的试用,终于找到了解决方案。以下解决方案已使用 Apollo Client v0.41.0 和 Swift 5 进行测试

import Foundation
import Apollo

class Network {
    static let shared = Network()
    
    private(set) lazy var apollo: ApolloClient = {

        let cache = InMemoryNormalizedCache()
        let store1 = ApolloStore(cache: cache)
        let authPayloads = ["Authorization": "Bearer <<TOKEN>>"]
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = authPayloads
        
        let client1 = URLSessionClient(sessionConfiguration: configuration, callbackQueue: nil)
        let provider = NetworkInterceptorProvider(client: client1, shouldInvalidateClientOnDeinit: true, store: store1)
        
        let url = URL(string: "https://<HOST NAME>/graphql")!
        
        let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider,
                                                                 endpointURL: url)
        
        return ApolloClient(networkTransport: requestChainTransport,
                            store: store1)
    }()
}
class NetworkInterceptorProvider: DefaultInterceptorProvider {
    override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
        var interceptors = super.interceptors(for: operation)
        interceptors.insert(CustomInterceptor(), at: 0)
        return interceptors
    }
}

class CustomInterceptor: ApolloInterceptor {
    
    func interceptAsync<Operation: GraphQLOperation>(
        chain: RequestChain,
        request: HTTPRequest<Operation>,
        response: HTTPResponse<Operation>?,
        completion: @escaping (Swift.Result<GraphQLResult<Operation.Data>, Error>) -> Void) {
        request.addHeader(name: "Authorization", value: "Bearer <<TOKEN>>")
        
        print("request :\(request)")
        print("response :\(String(describing: response))")
        
        chain.proceedAsync(request: request,
                           response: response,
                           completion: completion)
    }
}
Run Code Online (Sandbox Code Playgroud)


Ang*_*rus 6

终于我找到了答案。通过以下方式添加标题:

 let apolloAuth: ApolloClient = {
        let configuration = URLSessionConfiguration.default

        let token = UserDefaults.standard.value(forKey: "token")
        // Add additional headers as needed
        configuration.httpAdditionalHeaders = ["authorization":"\(token!)", "channel":"mobile"]
        let url = URL(string: "http://xxxx/graphql")!

        return ApolloClient(networkTransport: HTTPNetworkTransport(url: url, configuration: configuration))

    }()
Run Code Online (Sandbox Code Playgroud)

希望它会帮助某人。

  • 它从 0.34 版本开始停止工作,不再有 HTTPNetworkTransport (3认同)

Dan*_*lay 5

接受的解决方案现在已经过时了,因为 HTTPNetworkTransport 不再接受配置参数,而是URLSession直接接受一个而不是一个URLSessionConfiguration

这是一个示例,说明如何将每个请求的授权标头发送到 Apollo Client,如果找到,则从version 0.21.0Apollo Client(iOS) 的UserDefaults 中检索它

import Foundation
import Apollo

class Network {
    static let shared = Network()

    private(set) lazy var apollo: ApolloClient = {
        let token = UserDefaults.standard.string(forKey: "accessToken") ?? ""
        let url = URL(string: "http://localhost:4000/graphql")!

        let configuration = URLSessionConfiguration.default

        configuration.httpAdditionalHeaders = ["authorization": "Bearer \(token)"]

        return ApolloClient(
            networkTransport: HTTPNetworkTransport(url: url, session: URLSession(configuration: configuration))
        )
    }()
}
Run Code Online (Sandbox Code Playgroud)