Xác thực ứng dụng chat Realtime với Laravel Passport, SocketIO, Laravel Echo

Tram Ho

Hello các bạn lại là mình đây

Dạo này dịch bệnh ở VN căng thẳng quá chờ mãi không biết bao giờ con mới được về với đất mẹ. Nhớ giữ gìn sức khoẻ nhé các bạn để có sức còn code

Ở các bài trước trong series viết ứng dụng chat này mình dùng session để xác thực account của user cùng với đó là xác thực cho phía laravel echo. Thế nhưng ở các dự án thật thì việc xác thực qua JWT Token cũng rất phổ biến. Có khá nhiều bạn đã hỏi mình về vấn đề này.

Hôm nay tranh thủ rảnh mình viết luôn bài này để từ nay về sau các bạn có cái để xem trực tiếp và làm theo luôn chứ không cần phải lọ mọ search google nữa

Bài sẽ khá là ngắn chứ không dài dòng văn tự như các bài khác nên các bạn yên tâm nhé

Setup

Đầu tiên các bạn giúp mình clone source code cho bài này ở đây nhé.

Sau khi clone xong các bạn chạy lần lượt các command sau để cài các thư viện và 1 số setup liên quan nhé:

Các bạn update thông tin kết nối database trong .env cho khớp với môi trường của các bạn nhé, sau đó lại tiếp tục chạy các command sau:

Cuối cùng ta thử chạy app lên nhé:

Cuối cùng các bạn mở trình duyệt ở địa chỉ http://localhost:8000/chat, click Register để đăng kí tài khoản mới, sau khi đăng kí thành công các bạn sẽ được đưa vào màn hình chính như sau:

Các bạn thử gõ vài tin nhắn và gửi xem mọi thứ có oke hay không nhé, thử F5 lại trình duyệt để đảm bảo tin nhắn cũ được lưu trong database nhé.

Tổng quan project:

  • Ở project này mình dùng Laravel Passport cho authentication (login, register, gửi/load message). Mình dùng JWT Token để xác thực cho tất cả các APIs
  • Các routes cho Laravel mình khai báo ở routes/api.php, phía frontend dùng Vue Router
  • Tất cả các bước setup cho Laravel Passport mình đều follow theo docs của Laravel, không có gì kì diệu ở đây

Âu cây ta bước vào phần chính của ngày hôm nay thôi nào

Realtime

Điều kiện bắt buộc cho bài này đó là các bạn phải có Redis chạy trên máy nhé, trên windows cài Redis sẽ hơi chuối hơn 1 chút, nên mình khuyến khích các bạn dùng Docker để chạy Redis (1 nốt nhạc là lên)

Đầu tiên ta cài predis cho phía Laravel nhé:

Sau đó ở .env các bạn update lại phần cấu hình broadcast cho Laravel như sau:

Tiếp đến mở file config/database.php tìm mục redis và sửa lại 1 chút ở client và options như sau:

Tiếp đó mở file config/app.php, tìm mục providers bỏ comment dòng sau nhé:

Tiếp theo ta setup Laravel Echo Server nhé. Nếu máy các bạn chưa cài Laravel Echo Server thì các bạn chạy npm install -g laravel-echo-server trước đã nhé

Các bạn cho mình command sau:

Các bạn lần lượt chọn các option như sau nhé:

Tiếp theo ta mở file laravel-echo-server.json và update trường authEndpoint thêm vào tiền tố /api (vì bài này ta dùng toàn bộ là route /api mà):

Sau đó ta cần cài Laravel Echo cho phần frontend (VueJS) nhé:

Các bạn update lại file resources/views/layouts/app.blade.php thêm vào đoạn header ngay sau js/app.js cho mình như sau nhé:

Âu cây ta chạy Laravel Echo Server lên nhé:

Nhớ đảm bảo là laravel echo server chạy ngon nhé các bạn

Tiếp theo ta mở file resources/js/app.js ta update lại 1 chút như sau nhé:

Như các bạn thấy sự khác biệt của bài này so với các bài trước đó là ta chỉ khởi tạo connect tới Laravel echo server sau khi ta lấy được thông tin của user login hiện tại, mục đích để đảm bảo là user đã được xác thực, và đoạn quan trọng là ta truyền token vào trường auth để xác thực với phía Laravel echo server:

Sau đó ta quay lại trình duyệt bấm F5 để đảm bảo mọi thứ vẫn oke, kiểm tra Network để đảm bảo không có gì có lỗi:

Tiếp theo ta mở file resources/js/components/Chat.vue ở created ta thêm vào như sau:

Như ở trên các bạn cũng thấy đó là ta sẽ cho user join vào private channel tên là chatroom và lắng nghe event MessagePosted nếu thấy có tin nhắn mới thì in ra ở console.

Các bạn lưu lại và ta quay lại trình duyệt bấm F5 và để ý terminal nơi đang chạy Laravel Echo Server ta sẽ thấy lỗi in ra như sau:

Lỗi in ra ở đây là vì khi ta join vào channel chatroom thì Laravel Echo Server nó cần phải xác thực với phía Laravel, và vì ta đang đặt authEndpoint (trong laravel-echo-server.json) là /api/broadcasting/auth, mà cái route đó ta lại chưa hề khai báo nó ở đâu cả nên nó báo lỗi không tìm thấy.

Giờ ta mở file routes/api.php và khai báo cho route đó nhé:

Ổn rồi đó giờ ta quay lại trình duyệt bấm F5 1 lần nữa và quan sát ở terminal nơi đang chạy Laravel Echo Server sẽ thấy như sau nhé:

Vậy là ta đã hoàn thành việc xác thực với Laravel Echo Server bằng JWT Token rồi đó, mọi thứ còn lại thì y như những bài trước.

Đầu tiên ta tạo event MessagePosted (event này sẽ được gọi mỗi khi có tin nhắn được lưu thành công):

Sau đó ta mở file app/Events/MessagePosted.php và update 1 số phần như sau:

Cuối cùng ta mở file routes/api.php phần lưu tin nhắn ta thêm vào 1 dòng như sau:

Sau đó ta quay lại file Chat.vue và update created và thêm vào method scrollToBottom như sau:

Tiếp theo các bạn nhớ chạy queue:work nhé:

Ổn rồi đó giờ ta quay lại trình duyệt mở 2 tab, login vào 2 tài khoản khác nhau (mở tab ẩn danh nhé), chat thử nếu thấy realtime là ô xờ kê rồi đó:

Xác thực cho từng channel

Nếu các bạn để ý thì bài này ta không cần dùng tới file routes/channels.php, hiện tại thì ta đang return true; tức là cho user join vào bất kì private channel nào, thế nhưng thực tế thường ta sẽ có nhiều channel và với 1 user ta chỉ muốn cho họ join vào 1 vài channel nào đó thôi.

Từ phía Laravel Echo Server thì mỗi lần xác thực nó sẽ gửi kèm theo channel_name và ta có thể dựa vào đó để xử lý tuỳ ý:

Kết bài

Lâu lắm mới có 1 bài “tàu nhanh” như thế này.

Qua bài này các bạn thấy rằng việc dùng JWT Token để xác thực với Laravel Echo Server cũng không khó khăn lắm phải không nào? Nhưng vì mình thấy tài liệu và các bài tutorial trên mạng chủ yếu dùng session (như mình làm ở các bài trước), nên khi vào dự án thực tế mà dùng JWT thì bối rối không biết làm như thế nào, thì mong rằng qua bài này các bạn đã hiểu hơn về cách sử dụng nó.

Chúc các bạn thành công và hẹn gặp lại các bạn ở những bài sau

Chia sẻ bài viết ngay