如何使用 Mapbox Android SDK v10-beta20 向图块提供商提供身份验证令牌?

问题描述 投票:0回答:4

为了得到我的瓷砖,我这样做:

style(styleUri = Style.MAPBOX_STREETS) {
    +vectorSource(id = "parcel-source") {
    url("http://example.com/{z}/{x}/{y}.png")
}

但是我需要向图块提供商提供一个令牌,并带有像

Authorization: bearer [token]
这样的 HTTP 标头。

文档展示了HTTP拦截器的框架,但没有提供关于如何实现要实现的接口的5个功能的线索。 我在API参考中也找不到涉及的接口。 有一个针对类似问题的开放问题已记录。

此外,适用于 v9.5 的

解决方案 在 v10 中似乎不再可用(HttpRequestUtil 缺失)。

android mapbox mapbox-android
4个回答
2
投票
据观察,此方法仅在调试期间才能正常工作。 在进行发布构建时,由于重复的模块,会出现错误(因为我们不使用排除本地项目,并且外部库具有 Mapbox http 堆栈的重复模块)。

如果您想添加标头,请对 Mapbox 请求使用拦截器,如下所示:

https://github.com/mapbox/mapbox-maps-android/issues/610


1
投票
对于任何为此苦苦挣扎的人,您好,这是我的实现方法:

@MapboxModule(type = CommonHttpClient) class CustomMapboxOkHttpService : HttpServiceInterface { val map = MapboxOkHttpService() override fun setInterceptor(interceptor: HttpServiceInterceptorInterface?) { map.setInterceptor(interceptor) } override fun setMaxRequestsPerHost(max: Byte) { map.setMaxRequestsPerHost(max) } override fun request(request: HttpRequest, callback: HttpResponseCallback): Long { token?.let { request.headers["Authorization"] = "Bearer $it" } return map.request(request, callback) } override fun cancelRequest(id: Long, callback: ResultCallback) { map.cancelRequest(id, callback) } override fun supportsKeepCompression(): Boolean { return map.supportsKeepCompression() } override fun download(options: DownloadOptions, callback: DownloadStatusCallback): Long { return map.download(options, callback) } companion object { var token: String? = null } }
请勿排除文档中所述的公共库

此处


0
投票
我在将项目从 Mapbox 9 迁移到 10 时遇到了类似的问题。 我们曾经使用证书固定和拦截器创建自己的 okHttp 客户端,并将其提供给 Mapbox,这在 Mapbox 9 中相当容易,但无法找到一种简单的方法,而不需要按照建议替换整个 http 部分。在那里的文档中。

为了临时解决这个问题,我在java中使用了一个简单的概念,如果你提供相同的包结构,你可以替换特定的类

所以我做了以下事情:

  • 在我的项目中创建了一个新包(com.mapbox.common.module.okhttp)

  • 在mapbox sdk中搜索了一个名为LazyClient的类

  • 将类按原样复制到我的新目录中。

  • 通过添加证书固定和拦截器对负责创建 okhttp 客户端的方法进行了更改。

    /** copied from mapbox sdk with minor updates */ class LazyClient { private final SocketFactory socketFactory; private final boolean disableHttp2; private byte maxRequestsPerHost = 0; private static final long DEFAULT_CONNECT_TIMEOUT_SEC = 30; private static final long DEFAULT_READ_TIMEOUT_SEC = 60; private volatile OkHttpClient client; private boolean shouldEnablePinning = isPinningEnabled(); LazyClient(@Nullable SocketFactory socketFactory, boolean disableHttp2) { this.socketFactory = socketFactory; this.disableHttp2 = disableHttp2; } OkHttpClient get() { if (client == null) { synchronized (this) { if (client == null) { client = buildOkHttpClient(socketFactory, disableHttp2); assert client != null; if (maxRequestsPerHost != 0) { client.dispatcher().setMaxRequestsPerHost(maxRequestsPerHost); } } } } return client; } synchronized void setMaxRequestsPerHost(byte max) { maxRequestsPerHost = max; if (maxRequestsPerHost != 0) { synchronized (this) { OkHttpClient client = this.client; if (client != null) { client.dispatcher().setMaxRequestsPerHost(max); } } } } private static OkHttpClient buildOkHttpClient(@Nullable SocketFactory socketFactory, boolean disableHttp2) { OkHttpClient.Builder builder = CommonOkHttp.INSTANCE.builder() //new OkHttpClient.Builder() .eventListenerFactory(NetworkUsageListener.FACTORY) .connectTimeout(DEFAULT_CONNECT_TIMEOUT_SEC, TimeUnit.SECONDS) .readTimeout(DEFAULT_READ_TIMEOUT_SEC, TimeUnit.SECONDS) .addNetworkInterceptor(new CustomInterceptor()); if(isPinningEnabled()){ builder.certificatePinner(certPinner); } if (socketFactory != null) { builder.socketFactory(socketFactory); } if (disableHttp2) { // TODO: We are forcing HTTP1.1 since we are getting the following exception for download task for big files with HTTP2: // "okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR" builder.protocols(Arrays.asList(Protocol.HTTP_1_1)); } return builder.build();
    }

注意事项:

    您可以将其视为临时补丁,直到我们找到更合适的方法为止。
  • 这可能会在 Mapbox 的未来版本中出现问题。
  • 这种方法的主要优点是所需的编码量非常有限。

0
投票
我在尝试使用文档中描述的

HttpServiceInterface 方法时遇到了 这个问题

。
在 v10 中,还有另一个使用 
HttpServiceFactory.getInstance().setInterceptor
 的选项。这个接口实现起来要简单得多,并且每个方法都应该返回相同的对象。

这是我的方法:

class CustomMapboxIntercepter() : HttpServiceInterceptorInterface { override fun onRequest(request: HttpRequest): HttpRequest { request.headers["Authorization"] = "Bearer $token" return request } override fun onDownload(download: DownloadOptions): DownloadOptions { return download } override fun onResponse(response: HttpResponse): HttpResponse { return response } }
然后只需根据类设置拦截器即可:

HttpServiceFactory.getInstance().setIntercepter(CustomMapboxIntercepter())
这种方法还可以轻松地在构造函数中添加参数。

似乎在 v11 中也是可能的,但对 API 做了一些小改动:

将 HttpServiceFactory.getInstance().setInterceptor 替换为 HttpServiceFactory.setHttpServiceInterceptor。

© www.soinside.com 2019 - 2024. All rights reserved.