
ある時点で、ヘッダーに記載されている問題を解決する必要がありました。 私は長い間、自明なことを書くべきかどうかを考え、最終的には誰かに役立つかもしれないと決めました。
その理由は非常に簡単です-
非常にニッチなサイトの Androidクライアントの作成者として、同時にその管理者の数や共同創業者の数には含まれていません。 したがって、サイト管理者が実際に発効するまで、サイト管理者の決定を知りません。
少し前まで、このサイトでDDoS攻撃が始まり、管理者はCloudFlareからのDDoS保護をオンにしました。 したがって、以前はPOST + Cookieを介して標準の認証メカニズムを使用していたクライアントアプリケーションは、ユーザーの認証を停止しました。 管理者とのコミュニケーションは何にもつながりませんでした-「何ができるのか、モバイルクライアントがなければ、まったくできないよりはましです」。
当然、これはすべて評価に影響を及ぼし始め、非常に質素なレビューを引き起こしました。
解決策は、ページ上のブラウザの動作をシミュレートすることにより、CloudFlare保護をバイパスすることでした。 この特定のケースでは、CloudFlareは、ブラウザーが実行するハッシュ、キー、およびランダムなJavaScriptコードを使用し(難読化されたゴミのように見えるいくつかの算術演算を計算)、後でハッシュとキーと共に結果の数値を検証ページに送信します。 したがって、私たちのタスクは、javascriptタスクをインターセプトし、何らかの方法でそれを解決し、推測が正しいかどうかを尋ねることです。 その場合、パン(cf_clearance cookies)を取得します。 そうでない場合、503を取得します。
検索エンジンを調べてみると、
プロジェクトが非常によく似たものにつながるリンクが1つだけありました。 node.jsまたはPyExecJSの別の互換性のあるプロバイダーを使用してPythonで記述されています。 Pythonに敬意を払って、軽量のニッチアプリケーションでPythonを使用するのは不合理な贅沢であり、その統合には何時間もかかりました。 ソルバーコードをJavaで書き直すために戦略的な決定が行われました。
コードの作成中に発生したいくつかのメモ/あいまいさ:
- Mozilla RhinoがJSプロバイダーとして選ばれました。これは、最適化が無効になっているときに最適化されたDalvikバイトコード互換のインターフェースを提供します。
- 自動リクエストに固有のUserAgentはエラー503で拒否されます。「Java / 1.5.0_08」、「libcurl-agent / 1.0」、および同様の行はすぐに拒否されます。 何かを試す前に、最新のブラウザのUserAgentになりすましてください。
- Apacheの実装がHttpクライアントとして使用されました。 Android開発者が推進しているHttpURLConnectionよりも彼女を信頼していますが、これは好みの問題です。 OkHttpClientなど、互換性のある実装を使用できます
- 重要:WebViewでサイトのデータを後で表示する場合は、2つの考慮事項があります。
- httpクライアントには、webviewとまったく同じUserAgentが必要です(webviewでsettings.userAgentStringを使用します)
- cf_clearance cookieを受け取ったら、それをWebViewと同期する必要があります(以下のサンプルコード)
最終バージョンは以下です。 一緒にホイップされますが、すべてがどのように機能するかの基本的なアイデアを提供します。
private final static Pattern OPERATION_PATTERN = Pattern.compile("setTimeout\\(function\\(\\)\\{\\s+(var t,r,a,f.+?\\r?\\n[\\s\\S]+?a\\.value =.+?)\\r?\\n"); private final static Pattern PASS_PATTERN = Pattern.compile("name=\"pass\" value=\"(.+?)\""); private final static Pattern CHALLENGE_PATTERN = Pattern.compile("name=\"jschl_vc\" value=\"(\\w+)\""); abstract public HttpResponse getPage(URI url, HashMap<String, String> headers) throws IOException; abstract public CookieStore getCookieStore(); public boolean cloudFlareSolve(String responseString) {
クライアントコードはGPLv3の下で公開されているため、CloudFlareがそれを見つける可能性が高く、アルゴリズムの変更につながります。 それでも、私はあいまいさによるセキュリティの原則を支持しておらず、DDoSが低下する前にモバイルユーザーを許可するという問題を解決できました。
ご清聴ありがとうございました。 コメント内の質問/コメント。