簡體   English   中英

通過網絡服務公開網站

[英]Exposing a web site through web services

我知道我在問什么有點奇怪。 有一個 Web 應用程序(我們無法訪問其源代碼),我們希望將其一些功能公開為 Web 服務。

我正在考慮使用 Selenium WebDriver 之類的東西,所以我根據 Web 服務請求模擬應用程序上的 Web 點擊。

我想知道這是否是一個更好的解決方案或模式來做到這一點。

我將提到該應用程序是使用 Java、Spring MVC(它不是 SPA)和 Spring Security 編寫的。 並且有一個提供 SSO 的 CAS 服務器。

有多種實現方式。 在我看來,Selenium/PhantomJS 並不是最好的選擇,就好像 Web 設計得當一樣,您可以僅使用提供的 HTML 甚至某些 API 與其交互,而不需要所有的 CSS,並執行 javascript 異步請求。 由於您的頁面不是 SPA,因此很可能已經以 GET/POST 請求的形式存在“API”,您可能很幸運,沒有 CSRF 保護。

首先,您需要解決針對CAS的身份驗證。 oAuth 中有多種類型的身份驗證,但您應該獲得一個 API 令牌,使您能夠訪問應用程序。 此令牌應以 HTTP Header 或 Cookie 的形式添加到每個請求中。 理想情況下,此令牌不應過期,否則您將需要在您的應用程序中實現重新身份驗證邏輯。

身份驗證部分解決后,您將需要相當多的耐心,使用首選 Web 瀏覽器的 Web 檢查器打開目標網站,然后轉到“網絡”面板並以編程方式執行要運行的操作。 在那里,您將找到包含所有標頭和內容以及響應的請求。 這就是您需要編碼的內容。 有很多庫可以在 Java 中實現這一點。 如果您需要解析 HTML,您可以查看Jsop ,但要運行普通的 GET/POST 請求,請使用RestTemplate (在 Spring 中)或JAX-RS/Jersey 2 Client

如果查詢的結果在一段時間內保持不變,您可能會考慮實施緩存層以提高性能,或者您可以假設在 5 分鍾內,對同一查詢的響應將相同。

您可以使用您喜歡的語言/框架創建您的應用程序。 我建議從SpringBoot + MVC + DevTools 如果您需要解析一些 HTML,那將包含您需要的所有內容 + Jsoup。 稍后您可以根據需要添加緩存提供程序。

我們做一些類似於代表用戶訪問網上銀行的事情,抓取他的帳戶數據並獲得信用評分。 在大多數情況下,我們已經設法對移動應用程序進行逆向工程並嗅探流量以使用未記錄的 API。 在其他情況下,我們必須退回到網絡抓取。

您可以有兩種其他類型的應用程序來抓取:

  • 任何用戶的數據本質上都是相同的,例如亞馬遜中的產品列表
  • 數據特定於每個用戶,就像在銀行應用程序中一樣。

在第一種情況下,您可以讓刮板運行並填充本地數據庫並使用本地數據提供 Web 服務。 在后一種情況下,您不能這樣做,您需要根據用戶的請求抓取站點。

我從您的解釋中了解到您屬於后一種情況。

當網絡抓取時,你會發現非常困難的網絡應用程序:

  • 有些可能要求您將先前請求中的數據發送到下一個請求
  • 其他人使用 JavaScript 在客戶端呈現大部分數據

如果這兩個中的任何一個是您的情況,Selenium 將使您的實現更容易,但性能不高。

在沒有 selenium 的情況下實現第一個將需要您進行大量嘗試錯誤才能使事情正常工作,因為您將模擬請求並且您將需要知道客戶端需要什么數據。 而如果您使用 selenium,您將執行與瀏覽器相同的交互,從而發送預期的數據。 實現第二種情況需要你的爬蟲支持 JavaScript。 AFAIK 最好的支持是由 selenium 提供的。 HtmlUnit聲稱提供了公平的支持,我認為 JSoup 不提供對 JavaScript 的支持。

最后,如果您的解決方案花費太多時間,您可以通過通知機制緩解 Web 服務的問題,類似於 Webhooks 或Resthooks

  1. 您的 Web 服務的客戶端會請求提供一個 URI 的數據,他們希望在結果准備好時收到通知。
  2. 您的服務將立即響應請求的 ID,並開始在后台抓取必要的信息。
  3. 如果您使用瘦有效負載模型,當抓取完成后,您將響應存儲在您的數據存儲中,並帶有標識原始請求的 id。 此響應將作為資源公開。
  4. 您將在客戶端提供的 URI 上執行 HTTP POST 在請求正文中,您將添加響應資源的 URI。
  5. 客戶端現在可以GET響應資源,並且因為請求和響應具有相同的 ID,客戶端可以將兩者關聯起來。

Selenium 不是使用網絡服務的最佳方式。 Selenium 最好是一種自動化工具,主要用於測試應用程序。 假設已經開發了服務,我們需要做的第一件事就是驗證用戶請求。 這可以通過添加一個 HttpHeader 來完成,鍵為“授權”,值為“基本”+ Base64Encode(用戶名+“:”+密碼)

如果用戶有效(用戶登錄憑據與服務器中的憑據匹配),則生成唯一令牌,通過與用戶 ID 映射將令牌存儲在服務器中,並在響應標頭中設置相同的令牌或創建包含令牌的 cookie。 通過這樣做,我們可以通過僅在響應頭或 cookie 中查找令牌來避免驗證來自同一用戶的以下請求的憑據。 如果服務設計為每次 chcek 登錄,則每次發出請求時都需要在請求中設置“授權”標頭。

我認為使用webdriver的開銷很大,但這取決於您真正想要實現的目標。 根據您提供的信息,我寧願使用restTemplate實現,將適當的 http 消息發送到現有的 webapp,用一個漂亮的@service層包裝它,並在它上面構建您的 web 服務(rest 或 soap)。

身份驗證是一個配置問題,您可以使用@EnableOAuth2Sso將其打包在微服務中,並且您的restTemplate bean 會為您處理下划線身份驗證部分,這要歸功於 spring boot。

暫無
暫無

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

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