簡體   English   中英

在android中使用okhttp在webview中的每個請求中發送授權標頭

[英]Send authorization header with every request in webview using okhttp in android

我正在使用 WebView 來顯示網頁,但服務器需要一個來自我的 webview 的請求的授權令牌。 有誰知道這是否可能? 我在 #SO added -header-to-all-request-with- retrofit -2 中提到了這篇文章。 但我無法得到結果。

這是我的代碼(沒有我的編碼標准,我是初學者)

    public class TableViewTest extends AppCompatActivity {

    ScrollView scrollView;
    WebView webView;
    SharedPreferences pref;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_table_view_test);

        //final ProgressDialog pd = ProgressDialog.show(this, "", "Loading...", true);


        webView = (WebView) findViewById(R.id.webView1Id)

        webView.setVerticalScrollBarEnabled(true);
        webView.setHorizontalScrollBarEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setBuiltInZoomControls(true);

        webView.setWebViewClient(new WebViewClient() {

            @SuppressWarnings("deprecation")
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //return true load with system-default-browser or other browsers, false with your webView

                pref = getSharedPreferences("app", Context.MODE_PRIVATE);
                final String acToken = pref.getString("token", "DEFAULT");


                HashMap<String, String> headerMap = new HashMap<>();
                //put all headers in this header map
                headerMap.put("Authorization", acToken);


                view.loadUrl(url, headerMap);


                return false;
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }
        });

        webView.loadUrl("myurl");

    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        webView.restoreState(savedInstanceState);
    }


    public WebViewClient getWebViewClientWithCustomHeader(){

        pref = getSharedPreferences("app", Context.MODE_PRIVATE);
        final String acToken = pref.getString("token", "DEFAULT");

        return new WebViewClient() {

            @SuppressWarnings("deprecation")
            public WebResourceResponse shouldInterceptRequest(WebView view, String url){
                try {
                    OkHttpClient okHttpClient = new OkHttpClient();
                    Request request = new Request.Builder().url(url).addHeader("Authorization" , "Bearer " + acToken)
                            .build();

                    Response response = okHttpClient.newCall(request).execute();

                    return new WebResourceResponse(response.header("content-type", response.body().contentType().type()), // You can set something other as default content-type
                            response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                            response.body().byteStream());


                } catch (ClientProtocolException e) {
                    //return null to tell WebView we failed to fetch it WebView should try again.
                    return null;
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        };
    }
}

任何幫助表示贊賞

編輯

現在我能夠獲得服務器響應,但是在純 html 中,沒有正確呈現 css,不知道為什么。

這是新代碼,

    public class TableViewTest extends AppCompatActivity {

    ScrollView scrollView;
    WebView webView;
    SharedPreferences pref;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_table_view_test);

        //final ProgressDialog pd = ProgressDialog.show(this, "", "Loading...", true);

        String url = "myurl";
        pref = getSharedPreferences("app", Context.MODE_PRIVATE);


        webView = (WebView) findViewById(R.id.webView1Id);

        webView.setVerticalScrollBarEnabled(true);
        webView.setHorizontalScrollBarEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.setWebViewClient(wvc);

        webView.loadUrl("myurl");

    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        webView.restoreState(savedInstanceState);
    }


    public WebViewClient wvc =  new WebViewClient() {

            @SuppressWarnings("deprecation")
            public WebResourceResponse shouldInterceptRequest(WebView view, String url){
                try {
                    final String acToken = pref.getString("token", "DEFAULT");

                    OkHttpClient okHttpClient = new OkHttpClient();
                    Request request = new Request.Builder().url(url).addHeader("Authorization" , "Bearer " + acToken)
                            .build();

                    Response response = okHttpClient.newCall(request).execute();

                    return new WebResourceResponse(response.header("content-type", response.body().contentType().type()), // You can set something other as default content-type
                            response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                            response.body().byteStream());


                } catch (ClientProtocolException e) {
                    //return null to tell WebView we failed to fetch it WebView should try again.
                    return null;
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        };
}

並在堆棧跟蹤中找到了這個,在堆棧跟蹤中僅此而已

 E/DataReductionProxySettingListener: No DRP key due to exception:java.lang.ClassNotFoundException: com.android.webview.chromium.Drp

最后,這將糾正 html 渲染問題(對不起,我之前沒有注意到這一點)。

更改content-type

return new WebResourceResponse(response.header("content-type", response.body().contentType().type()), // You can set something other as default content-type
                        response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                        response.body().byteStream());

text/html ,所以新代碼是

return new WebResourceResponse(response.header("text/html", response.body().contentType().type()), // You can set something other as default content-type
                    response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                    response.body().byteStream());

如果我的解決方案需要任何修改,請隨時進行編輯。 始終接受更好的解決方案。 快樂編碼......謝謝大家#SO准備提供幫助。

Sudheesh 的回答很棒,這里是更新版本,因為shouldOverrideUrlLoading(WebView view, String url)在 API 21 中已被棄用:

webView.setWebViewClient(new WebViewClient() {
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest webResourceRequest) {
                // Filter out any requests we not interested in
                if (webResourceRequest.getUrl().getHost() == null ||
                        !webResourceRequest.getUrl().getHost().equals(MyAPI.getServer().toHost())) {
                    return super.shouldInterceptRequest(view, webResourceRequest);
                }
                try {
                    OkHttpClient okHttpClient = new OkHttpClient();
                    Request request = new Request.Builder().url(webResourceRequest.getUrl().toString())
                            .addHeader(HttpConnector.DefaultConnector().getAuthorizationHeaderKey(), HttpConnector.DefaultConnector().getAuthorizationHeaderValue())
                            .build();
                    Response response = okHttpClient.newCall(request).execute();
                    return new WebResourceResponse(response.header("text/html", response.body().contentType().type()), // You can set something other as default content-type
                            response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                            response.body().byteStream());
                } catch (ClientProtocolException e) {
                    //return null to tell WebView we failed to fetch it WebView should try again.
                    return null;
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });

這可能無法回答您的問題,但我認為這對遇到類似問題的其他人會有所幫助。

如果服務器資源需要像這樣的基本身份驗證標頭Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=那么你應該像這樣覆蓋 WebViewClient 中的onReceivedHttpAuthRequest方法。

webView.webViewClient = object : WebViewClient() {

    override fun onReceivedHttpAuthRequest(view: WebView?, handler: HttpAuthHandler?, host: String?, realm: String?) {
        handler?.proceed("username", "password")
    }

}

另請注意,如果可能,您應該始終避免攔截 WebView 請求。 在此處閱讀更多相關信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM