验证您的操作
验证并未包含在GraphQL 规范中。本页面旨在提供一些常见场景的指导,但并不全面。
使用OkHttp验证您的HTTP请求
OkHttp拦截器是添加"Authorization"
头信息到您的HTTP请求的简单方法。
OkHttp拦截器已经存在很长时间,并且工作良好,但只能与Apollo Kotlin(适用于Android和JVM)一起使用。
使用Apollo HttpInterceptor验证您的HTTP请求
为了以多平台的方式验证您的HTTP请求,您可以使用Apollo HttpInterceptor。
HttpInterceptor是跨平台的,并使用了与OkHttp非常相似的API。
class AuthorizationInterceptor() : HttpInterceptor {private val mutex = Mutex()override suspend fun intercept(request: HttpRequest, chain: HttpInterceptorChain): HttpResponse {var token = mutex.withLock {// get current token}val response = chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())return if (response.statusCode == 401) {token = mutex.withLock {// get new token}chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())} else {response}}}
对于更高级的示例,您可以查看AuthorizationInterceptor集成测试
认证您的WebSocket
通常使用特定的连接有效负载来处理WebSocket的认证
val apolloClient = ApolloClient.Builder().httpServerUrl("https://127.0.0.1:8080/graphql").webSocketServerUrl("https://127.0.0.1:8080/subscriptions").wsProtocol(SubscriptionWsProtocol.Factory(connectionPayload = {// some servers use "authorization" directlymapOf("authorization" to token)// others require to wrap in a "headers" mapmapOf("headers" to mapOf("authorization" to token))// others will expect different maps// refer to your backend docs for the actual map to use})).build()
另外,您也可以在初始WebSocket握手请求中发送头部信息
val apolloClient = ApolloClient.Builder().httpServerUrl("https://example.com/graphql").subscriptionNetworkTransport(WebSocketNetworkTransport.Builder().serverUrl("https://example.com/subscriptions").addHeader("Authorization", authorization).build()).build()
更新您的WebSocket令牌
当使用经过认证的订阅通过WebSocket时,您可能需要刷新认证令牌,因为它已无效或已过期。
ⓘ 注意
如果您的用户注销了,您可能需要考虑创建一个新的ApolloClient
。这将确保除WebSocket以外的所有其他状态(例如,缓存)都是新的,而不是不同用户之间共享的。
有时WebSocket将发出一个错误,您可以使用webSocketReopenWhen
来创建一个新的WebSocket。其他时候,这些信息会来自应用的其他地方,并且您必须强制断开WebSocket。
首先定义自己的异常
class WebSocketReconnectException: Exception("The WebSocket needs to be reopened")
val apolloClient = ApolloClient.Builder().httpServerUrl("https://127.0.0.1:8080/graphql").webSocketServerUrl("https://127.0.0.1:8080/subscriptions").wsProtocol(SubscriptionWsProtocol.Factory(connectionPayload = {// the connection_init payload// This is an example. You will most likely have to tweak it for your backendmapOf("Authorization" to token)})).webSocketReopenWhen { e, attempt ->if (e is WebSocketReconnectException) {true} else {// Another WebSocket error happened, decide what to do with it// Here we're trying to reconnect at most 3 timesattempt < 3}}.build()
当您需要重新打开WebSocket时,调用closeConnection
:
apolloClient.subscriptionNetworkTransport.closeConnection(WebSocketReconnectException())`
WebSocket将关闭并重新打开,使用全新的connectionPayload
。