Melewati Batas Pencarian LinkedIn dengan Bermain dengan API

[Karena ekstensi saya mendapat banyak perhatian dari penonton asing, saya menerjemahkan artikel asli saya ke dalam bahasa Inggris] .

Batasi


Menjadi jaringan profesional berperingkat teratas, LinkedIn, sayangnya, untuk akun gratis, memiliki batasan seperti Batas Penggunaan Komersial (CUL). Kemungkinan besar, Anda, sama seperti saya sampai saat ini, belum pernah bertemu dan tidak pernah mendengar tentang hal ini.

gambar

Maksud dari CUL adalah bahwa ketika Anda terlalu sering mencari orang di luar koneksi / jaringan Anda, hasil pencarian Anda akan dibatasi dengan hanya 3 profil yang menunjukkan bukan 1000 (100 halaman dengan 10 profil per halaman secara default). Seberapa sering 'diukur' tidak ada yang tahu, tidak ada metrik yang tepat; algoritme memutuskannya berdasarkan tindakan Anda - seberapa sering Anda mencari dan berapa banyak koneksi yang telah Anda tambahkan. CUL gratis direset di tengah malam PST pada tanggal 1 setiap bulan kalender, dan Anda mendapatkan 1000 hasil pencarian lagi, untuk siapa yang tahu berapa lama. Tentu saja, akun Premium tidak memiliki batasan seperti itu .

Namun, belum lama ini, saya sudah mulai main-main dengan LinkedIn mencari beberapa proyek hewan peliharaan, dan tiba-tiba terjebak dengan CUL ini. Jelas, saya tidak terlalu menyukainya; Lagi pula, saya belum menggunakan pencarian untuk tujuan komersial. Jadi, pikiran pertama saya adalah menjelajahi batas ini dan mencoba untuk melewatinya.

[Klarifikasi penting - semua bahan sumber dalam artikel ini disajikan semata-mata untuk tujuan informasi dan pendidikan. Penulis tidak menganjurkan penggunaannya untuk tujuan komersial.]


Pembaruan Penting - LinkedIn memperhitungkan backdoor ini dan baru-baru ini mereka memperbaikinya. Backdoor dan plugin tidak berfungsi lagi.



Mempelajari Masalahnya


Apa yang kami dapatkan: alih-alih 10 profil dengan pagination, alat pencarian hanya menampilkan 3, yang diikuti oleh 'rekomendasi' untuk membeli akun Premium dan kemudian Anda melihat profil kabur yang tidak dapat diklik lainnya.

Yang pertama kali Anda miliki sebagai pengembang adalah membuka Alat Pengembang Browser untuk memeriksa profil tersembunyi / buram - mungkin Anda dapat menghapus beberapa gaya yang bertanggung jawab atas kabur, atau mengekstrak data dari blok tata letak / markup. Tapi, seperti yang bisa diharapkan, profil ini ditampilkan hanya sebagai gambar placeholder dan tidak mengandung data apa pun.

gambar

Oke, sekarang mari kita pergi ke tab Jaringan dan memeriksa apakah hasil pencarian alternatif benar-benar hanya mengembalikan 3 profil. Jadi, kami menemukan permintaan yang kami minati - β€œ/ api / search / blended” - dan lihat jawabannya.

gambar

Profil terdapat dalam array `Included`, tetapi sudah ada 15 entitas di dalamnya. Dalam kasus ini, 3 yang pertama adalah objek dengan data tambahan - setiap objek berisi informasi pada profil tertentu (misalnya, jika profilnya adalah Premium).

12 profil berikutnya adalah nyata - sebenarnya hasil pencarian tersebut, yang hanya 3 yang akan ditampilkan kepada kami. Seperti yang sudah bisa Anda tebak, LinkedIn hanya menampilkan profil yang menerima informasi tambahan (3 objek pertama). Misalnya, jika Anda menjelajahi respons pencarian dari profil tanpa batas, 28 entitas akan dikembalikan - 10 objek dengan info tambahan dan 18 profil.

Respons untuk profil tanpa batas
gambar

gambar

Saya belum yakin mengapa ada lebih dari 10 profil yang dikembalikan, sementara 10 diminta, dan profil itu tidak ditampilkan kepada pengguna - Anda tidak akan melihatnya bahkan di halaman berikutnya. Jika Anda menganalisis URL permintaan, Anda akan melihat bahwa jumlah = 10 (berapa banyak profil untuk dikembalikan dalam respons, 49 adalah maks.).

gambar

Setiap komentar tentang hal ini akan sangat dihargai.

Eksperimen


Oke, sekarang kami tahu hal yang paling penting - respons datang dengan lebih banyak profil daripada yang ditunjukkan LinkedIn kepada kami. Jadi, kita bisa mendapatkan lebih banyak data, meski dengan CUL. Mari kita coba tarik API sendiri langsung dari konsol, menggunakan fetch.

gambar

Seperti yang diharapkan, kami mendapatkan kesalahan 403. Ini adalah masalah keamanan - di sini kami tidak mengirim token CSRF ( CSRF di Wikipedia ). Singkatnya, ini adalah token unik yang ditambahkan ke setiap permintaan, yang diperiksa di sisi server untuk keaslian.

gambar

Anda dapat menyalinnya dari permintaan lain yang berhasil atau dari cookie, di mana itu disimpan di bidang 'JSESSIONID'.

Di mana menemukan token
Tajuk permintaan lainnya:

gambar

Dari cookie, menembus konsol:

gambar

Ayo coba lagi; kali ini, kami melewati pengaturan untuk mengambil. Dalam pengaturan, kami menentukan token CSRF kami sebagai parameter di header.

gambar

Berhasil, semua 10 profil dikembalikan. : tada:
Karena perbedaan dalam tajuk, struktur respons sedikit berbeda dari apa yang ada dalam permintaan awal. Anda bisa mendapatkan struktur yang persis sama jika Anda menambahkan 'Terima:' aplikasi / vnd.linkedin.normalisasi + json + 2.1 'ke objek kami, di sebelah token CSRF.

Contoh tanggapan dengan tajuk yang ditambahkan
gambar

Lebih lanjut tentang Header Terima

Apa Selanjutnya?


Sekarang Anda dapat mengedit (secara manual atau otomatis) parameter `start` yang menentukan indeks, mulai dari yang kami dapat menerima 10 profil (secara default = 0) dari seluruh hasil pencarian. Dengan kata lain, menambahnya dengan 10 setelah setiap permintaan, kami mendapatkan pagination biasa, 10 profil per halaman.

Pada tahap ini, saya punya cukup data dan kebebasan untuk terus mengerjakan proyek hewan peliharaan. Tetapi akan menjadi dosa untuk tidak mencoba menampilkan data ini segera karena itu ada di tangan saya. Kami tidak akan menyelam ke Ember yang digunakan untuk frontend. Karena JQuery terintegrasi pada situs web, Anda dapat menggali dari ingatan Anda pengetahuan tentang sintaks dasar, dan membuat hal-hal berikut dalam beberapa menit.

Kode JQuery
/* render the block, receive profile data, and insert the block in the profiles' list, using this data */ const createProfileBlock = ({ headline, publicIdentifier, subline, title }) => { $('.search-results__list').append( `<li class="search-result search-result__occluded-item ember-view"> <div class="search-entity search-result search-result--person search-result--occlusion-enabled ember-view"> <div class="search-result__wrapper"> <div class="search-result__image-wrapper"> <a class="search-result__result-link ember-view" href="/in/${publicIdentifier}/"> <figure class="search-result__image"> <div class="ivm-image-view-model ember-view"> <img class="lazy-image ivm-view-attr__img--centered EntityPhoto-circle-4 presence-entity__image EntityPhoto-circle-4 loaded" src="http://www.userlogos.org/files/logos/give/Habrahabr3.png" /> </div> </figure> </a> </div> <div class="search-result__info pt3 pb4 ph0"> <a class="search-result__result-link ember-view" href="/in/${publicIdentifier}/"> <h3 class="actor-name-with-distance search-result__title single-line-truncate ember-view"> ${title.text} </h3> </a> <p class="subline-level-1 t-14 t-black t-normal search-result__truncate">${headline.text}</p> <p class="subline-level-2 t-12 t-black--light t-normal search-result__truncate">${subline.text}</p> </div> </div> </div> <li>` ); }; // fetch data and render the profiles const fetchProfiles = () => { // token const csrf = 'ajax:9082932176494192209'; // bject with the request settings, pass the token const settings = { headers: { 'csrf-token': csrf } } // request URL, with a dynamic start index at the end const url = `https://www.linkedin.com/voyager/api/search/blended?count=10&filters=List(geoRegion-%3Ejp%3A0,network-%3ES,resultType-%3EPEOPLE)&origin=FACETED_SEARCH&q=all&queryContext=List(spellCorrectionEnabled-%3Etrue,relatedSearchesEnabled-%3Etrue)&start=${nextItemIndex}`; /* make a request, for each profile in the response call the block rendering, and then increment the starting index by 10 */ fetch(url, settings).then(response => response.json()).then(data => { data.elements[0].elements.forEach(createProfileBlock); nextItemIndex += 10; }); }; // delete all profiles from the list $('.search-results__list').find('li').remove(); // insert the 'download profiles' button $('.search-results__list').after('<button id="load-more">Load More</button>'); // add the functionality to the button $('#load-more').addClass('artdeco-button').on('click', fetchProfiles); // set the default profile index for the request window.nextItemIndex = 0; 

Jika Anda melakukan tindakan ini langsung di konsol pada halaman pencarian, Anda akan menambahkan tombol yang memuat 10 profil baru setiap kali Anda mengkliknya, dan menjadikannya sebagai daftar. Tentu saja, Anda harus mengubah token dan URL dengan tepat ke yang diperlukan. Blok profil akan berisi nama, posisi pekerjaan, lokasi, tautan ke profil, dan gambar placeholder.

gambar

Kesimpulan
Karena itu, dengan upaya minimal, kami dapat menemukan titik lemah dan mendapatkan kembali opsi pencarian kami tanpa batasan. Itu sudah cukup untuk menganalisis data dan jalurnya dan melihat ke dalam permintaan itu sendiri.

Saya tidak dapat mengatakan bahwa ini adalah masalah serius bagi LinkedIn karena itu tidak mewakili ancaman. Yang terburuk yang bisa terjadi adalah kehilangan keuntungan karena "memotong" seperti itu, yang memungkinkan Anda untuk tidak membeli akun Premium. Mungkin, respons server semacam itu diperlukan agar bagian lain dari situs web dapat berfungsi dengan benar, atau ini hanya kemalasan pengembang yang kekurangan sumber daya, yang tidak memungkinkan melakukan yang lebih baik (CUL muncul pada Januari 2015, sebelum tidak ada batasan sama sekali).

PS


Ps lama
Tentu, kode jQuery adalah contoh kemampuan yang cukup primitif. Saat ini, saya telah membuat ekstensi browser untuk memenuhi kebutuhan saya. Ini menambahkan tombol kontrol dan membuat profil berfitur lengkap dengan gambar, tombol undangan, dan koneksi timbal balik. Plus, secara dinamis mengumpulkan filter lokasi, perusahaan, dan hal-hal lain, dan menarik token dari cookie. Jadi Anda tidak perlu melakukan hardcode apa pun. Juga, ekstensi menambahkan bidang pengaturan tambahan, misalnya "berapa banyak profil yang diminta sekaligus, hingga 49."

contoh

Saya masih mengerjakan ekstensi ini, dan saya berencana untuk membuatnya tersedia untuk umum.
Pesan saya jika Anda tertarik.

Dengan permintaan populer untuk merilis ekstensi ini sebagai produk open-source, saya membuat ekstensi browser dan mempostingnya untuk penggunaan umum (gratis dan bahkan tanpa penambang). Tidak hanya memiliki fungsi bypass batas tetapi juga beberapa fitur lainnya. Anda dapat melihatnya dan mengunduhnya di sini - adam4leos.imtqy.com

Karena ini adalah versi alfa, jangan ragu untuk memberi tahu saya tentang bug, ide Anda, atau bahkan tentang a
UI dingin dirajam. Saya terus meningkatkan ekstensi dan akan memposting versi baru dari waktu ke waktu.

Pembaruan Penting - LinkedIn memperhitungkan backdoor ini dan baru-baru ini mereka memperbaikinya. Backdoor dan plugin tidak berfungsi lagi.

Source: https://habr.com/ru/post/id466801/


All Articles