Bắt chước Facebook và Google, cùng viết hệ thống “theo dõi” người dùng với Cookie

Ở bài trước, mình đã “vạch mặt” Facebook và Google theo dõi lịch sử duyệt web của người dùng.

Ở bài này, để hiểu rõ hơn cơ chế hoạt động của các hệ thống này, chúng ta cùng viết một hệ thống “theo dõi” đơn giản hơn, sử dụng cookie nhé.

Thật ra, những chiêu trò track người dùng này… không có gì cao siêu ghê gớm. Hệ thống này được viết bằng NodeJS, chỉ có vài chục dòng code thôi.  Các bạn cùng xem thử nhé

Demo ngay cho nóng

Các bạn có thể vào xem demo hệ thống tại đây: https://codedao-tracking.glitch.me

Để kiểm tra hệ thống có thật sự hoạt động hay không, hãy thử vào các trang có script tracking này rồi vào lại xem log nhe:

Cơ chế hoạt động

Hệ thống hoạt động theo cơ chế rất đơn giản:

  1. Khi bạn vào hệ thống lần đầu, server sẽ check cookie trong HTTP Request. Nếu bạn chưa có cookie, server sẽ tạo 1 cookie random và gửi về trình duyệt.
  2. Ở 1 số trang như hoclaptrinh.toidicodedao.com, security.toidicodedao.com, jav-idol.toidicodedao.com, thậm chí là chính blog này, mình có cài script để tracking.
  3. Khi bạn vào các trang này, script ở client sẽ gửi request tới server (bao gồm trang web bạn vào, thời gian), đính kèm với cookie. Dựa theo cookie này, server sẽ lưu lại log vào database MongoDB.
  4. Khi bạn vào trang web, server sẽ dựa theo cookie của bạn để hiển thị log những trang bạn đã ghé.

Cùng bắt tay vào code

Mình sử dụng NodeJS để code cho tiện. Thay vì phải tìm máy chủ và host để deploy, mình dùng Glitch.com – một công cụ build và deploy app NodeJS cực nhanh.

Giao diện của Glitch.com, vô cùng vui nhộn

Đây là một tool khá tiện, code ngay tại chỗ, app được build và có host ngay. Mình chỉ việc code, còn lại trang https://sleepy-fuel.glitch.me là hệ thống tự deploy cả.

Chúng ta cùng làm những điều mình nói phía trên nhé.

  1. Khi bạn vào trang web, nếu không có cookie thì server tạo cookie và ghi xuống client


app.get("/", function (request, response) {
if (!request.cookies.id) {
const randomId = idGenerator.getRandomId();
response.cookie('id', randomId , { maxAge: 30*24*3600*1000 } ); // Cookie 30 ngày
}
response.sendFile(__dirname + '/views/index.html');
});

view raw

index.js

hosted with ❤ by GitHub

2. Tạo 1 đoạn script để gửi cookie của người dùng lên server


// Tạo iframe ẩn để set cookies
var iframe = document.createElement('iframe');
iframe.style.display = "none";
iframe.src = "https://sleepy-fuel.glitch.me";
document.body.appendChild(iframe);
// Gửi cookies và thông tin lên server
setTimeout(() => {
fetch('https://sleepy-fuel.glitch.me/logWrite', {
method: 'GET',
credentials: 'include'
});
}, 2000);

view raw

track.js

hosted with ❤ by GitHub

Trong nhiều trường hợp, người dùng sẽ không ghé trang chính mà chỉ ghé trang có gắn script nên chưa có cookie. Do đó chúng ta tạo 1 iframe ẩn, mở trang chính để set cookie cho người dùng. Sau đó ta gọi AJAX call đến url logWrite để ghi log.

Để track người dùng, các trang web chỉ cần thêm đoạn mã JavasSript phía dưới vào code HTML.

Khi muốn gắn quảng cáo, thông thường bạn cũng sẽ phải thêm 1 số script tracking vào trang web của mình

3. Viết hàm logWrite trên server, hàm này sẽ ghi lại id của người dùng (trong cookie) và địa chỉ web họ đã ghé thăm.


// Tracking API
app.get('/logWrite', function(request, response) {
// Lấy id người dùng thông qua cookie
const userId = request.cookies.id;
const referrer = request.header('Referer').replace(/\/$/, "");;
const time = new Date();
const log = {userId, referrer, time};
// Ghi log vào database
db.log.insert(log, (err, result) => {
response.header('Access-Control-Allow-Origin', referrer);
response.header('Access-Control-Allow-Credentials', 'true');
response.json(result);
});
});

view raw

server.js

hosted with ❤ by GitHub

4. Khi người dùng ghé vào trang web tracking tại https://codedao-tracking.glitch.me, ta lấy userid từ cookie và hiển thị log tương ứng.


app.get('/log', function(request, response) {
// Tìm những log trong database có userId trùng với id trong cookie
// Sắp xếp theo thứ tự thời gian
db.log.find({ userId: request.cookies.id }).sort( {time: -1} , (err, docs) => {
response.json({ id: userId, logs: docs });
});
});

view raw

log.js

hosted with ❤ by GitHub

Thế là xong rồi đấy, đơn giản quá phải không nào!

Cách không thủ vật – Track không cần script

Tất nhiên, đôi khi chúng ta không làm chủ một trang web nên không thể thêm script tracking vào được. Vậy thì còn cách nào không? Dĩ nhiên là có!

Không cần thêm JavaScript, mình có thể track bạn chỉ bằng một tấm hình “vô hại” như thế này:

Source code: <img src="https://sleepy-fuel.glitch.me/tracking.jpg" />

Khi trình duyệt hiển thị tấm hình này, nó gửi một HTTP Request có kèm cookie lên server. Server tiếp tục đọc và lưu vào log. Code cũng khá đơn giản thôi.


app.get('/tracking.jpg', function(request, response) {
// Lấy id từ cookie và ghi log như bình thường
const userId = request.cookies.id;
const referrer = (request.header('Referer') || 'Empty').replace(/\/$/, "");;
const time = new Date();
const log = { userId, referrer, time };
db.log.insert(log, (err, result) => {
// Trả ra file ảnh "vô hại"
response.sendFile(__dirname + '/public/track.jpg');
});
});

view raw

image.js

hosted with ❤ by GitHub

Đây là chiêu mà các bạn marketing thường dùng. Họ thường đính kèm link ảnh trong post của các forum, trong email để đếm số người xem, kiểm tra email đã được đọc chưa v…v

 

Note: Gần đây 1 số trình duyệt đã chặn cookie từ ảnh (để tránh bị tracking) nên chiêu này dùng lúc được lúc không nhe.

Xoá cookie không khỏi nắng

Tất cả những chiêu trò tracking nãy giờ đều được thực hiện bằng cookie. Vậy hẳn bạn sẽ có nghĩ là: “Xoá cookie hoặc sử dụng trình duyệt ẩn danh là xong! Track bố mày bằng đít nhé!”.

Bạn nhầm rồi! Hãy đọc lại bài viết trước nha, còn nhiều chiêu trò đáng sợ lắm. Hãy cùng vào lại trang web tracking và bấm “Xem thông tin của thí chủ” nha.

Sau đó, mở trình duyệt ẩn danh lên và bấm “Xem thông tin”! Mã số khác nhau (vì không lưu cookie), nhưng 2 thông tin này giống nhau y hệt.

Khác cookie, nhưng thông tin giống nhau như hai giọt nước

Mình có thể dựa vào những thông tin này để track bạn mà không cần cookie hay không? Dĩ nhiên là có! Đáng sợ chưa! Cơ mà vì mình là người tốt nên mình không làm đâu.

Do vậy, các bạn đừng lầm tưởng rằng dùng trình duyệt ẩn danh tuyệt đối an toàn nhé! Dĩ nhiên, các bạn có thể đánh lừa hệ thống bằng cách đổi browser, fake IP, dùng VPN, đổi user-agent.

Kết

Thông qua bài viết này, các bạn đã biết được cách hiện thực một hệ thống tracking bằng cookie cực kì đơn giản mà khá mạnh.

Trong bài này cũng vậy, mình chỉ làm demo thôi, không lưu bất kì thông tin gì của các bạn đâu nên mọi người đừng lo ha!

Xin kết thúc bài viết bằng một câu mình đã nói ở bài viết trước:

Có một bàn tay vô hình theo dõi từng bước chân của bạn trên Internet, kể cả khi bạn lướt web mua hàng, khi bạn nghe nhạc Sơn Tùng cho dễ ỵ, khi bạn xem porn để giải lao sau những ngày học tập căng thẳng.

May mắn thay cho chúng ta, đa phần việc tracking này được dùng cho mục đính tốt đẹp (quảng cáo, cải thiện trải nghiệm).

Hi vọng các bạn xem để học hỏi chứ đừng áp dụng làm điều xấu nhé!

 

Các bạn có thể xem source code tại: https://github.com/conanak99/SimpleCookieTracking hoặc vào Glitch để code và chỉnh sửa ngay nhe: https://glitch.com/~codedao-tracking

8 thoughts on “Bắt chước Facebook và Google, cùng viết hệ thống “theo dõi” người dùng với Cookie”

  1. Anh ơi cho em xin 1 vài source code project được xây dựng trên struts 1 với struts 2 để em học được k ạ 😀

    Liked by 1 person

  2. rất cảm ơn anh “) e cũng đang cần cái này luôn!
    Một cái góp ý là bạn nào chạy local sẽ ko lấy đc IP do request headers sẽ ko có ‘x-forwarded-for’ nên sẽ bị lỗi unidentified khi Xem thông tin.
    Chỉ cần bắt ngoại lệ là được.

    Like

  3. Bài viết khá hay, ad cho mình hỏi làm sao để ghi thêm thông tin của /info vào database ạ? Cám ơn ad

    Like

Leave a comment