验证您的操作
身份验证不包括在GraphQL规范中。本页旨在提供一些常见场景的指导,但并非详尽无遗。
使用 OkHttp 验证您的 HTTP 请求
OkHttp 拦截器是一种简单的方法,可以将"Authorization"
头添加到您的 HTTP 请求中。
OkHttp 拦截器已经存在很长时间,并且工作良好,但只在 Android 和 JVM 上工作。
使用 Apollo HttpInterceptor 验证您的 HTTP 请求
为了以多平台的方式验证您的 HTTP 请求,您可以使用 ApolloHttpInterceptor。
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://127.0.0.1:8080/graphql").subscriptionNetworkTransport(WebSocketNetworkTransport.Builder().serverUrl("https://127.0.0.1:8080/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
重新打开。