Tạo module Backend, Frontend và Api với Laravel 5.7 (version 2)

Hôm nay có thời gian rãnh rỗi. Tui viết lại bài tạo module version 2 để cập nhật lại cho bài lần trước, về cơ bản thì cũng không khác gì, nhưng có một số thay đổi khi load route và views cho từng module. Bài này tui dùng Laravel 5.7 nhé, và coi như các bạn đã cài WAMP Server rồi nhé.

1. Tạo project:

Hôm nay là ngày 01/12, cho nên tui chọn tên project là hestia nhé. Giả sử, thư mục WEB_ROOT cho project này hiện lại là E:\Server\www\learning:

Chờ đến khi nó chạy xong như hình sau:

Khi đó trong thư mục hestia, chúng ta sẽ có cây thư mục như sau:

Để đơn giản, tui không tạo virtual host để trỏ vào thư mục hestia/public mà tui sẽ dùng cái Web Server có sẵn của laravel để run cái project này luôn. Chuyển vào thư mục hestia, run command sau:

Mở Chrome hay FireFox lên, chạy http://localhost:9000/, nếu nó hiện ra cái trang Laravel to đùng thì ổn.

Nếu các bạn bỏ tham số –port=9000 thì mặc định Web Server nó sẽ listen ở port 8000 nha.

2. Tạo module Backend, Frontend và Api:

Tại thư mục app, các bạn tạo thư mục Modules và các thư mục con tương ứng như sau:

Chú ý: trong thự mục Modules/Api, không có thư mục Views nha, lý do là Api không cần render views.

Tại thư mục config, các bạn tạo một file tên là modules.php:

Với nội dung như sau:

Mục đích của việc tạo file modules.php để đễ dàng quản lý việc load routes cũng như views theo từng module tương ứng. Tiếp theo, các bạn tạo một Service Provider để nó kiểm tra và load module tương ứng. Tại thư mục app/Modules, các bạn tạo một file tên là ModuleServiceProvider.php:

Với nội dung sau (hơi bị dài nha):

Thực chất là tui sẽ dùng cái ModuleServiceProvider.php này để thay thế cho cái file Provider/RouteServiceProvider.php mặc định của Laravel.

Đối với hàm mapApi(), do tui muốn là có nhiều file route tương ứng với từng version cho api, kiểu như là:

  • v1.route.php, tương ứng với api/v1/*
  • v2.route.php, tương ứng với api/v2/*

Cho nên sẽ có phần scandir cho thư mục Api/Routes để lấy cái version name cho từng route.

Edit file config/app.php để load cái Modules/ModuleServiceProvider.php và unload cái Provider/RouteServiceProvider.php. Mở file config/app.php, tìm đến cái array ‘providers’:

comment cái dòng App\Providers\RouteServiceProvider::class,

và thêm App\Modules\ModuleServiceProvider::class,

Để cho chắc chắn rằng Laravel 5 nó hiểu cái namespace App\Modules, chúng ta mở file composer.json, tìm đến mục psr-4 nằm trong mục autoload, thêm “App\\Modules”: “app/Modules” ngay bên dưới “App\\”: “app/”:

Để chắc ăn, các bạn nên stop Web Server (ấn Ctrl + C) và start lại nhé.

3. Tạo route cho từng module

Ở phần này, tui sẽ map route với Controller@action nhé.

3.1. Backend module:

Các bạn tạo các file như sau:

Nội dung các file tương ứng như sau:

Backend/Controllers/Controller.php:

Backend/Controllers/HomeController.php:

Backend/Routes/web.php:

Backend/Views/home/welcome.blade.php:

Kết quả:

3.2. Frontend Module:

Cũng tạo các file giống như Backend:

Nội dung thì y chang, chỉ khác cái namespace và nội dung message:

Frontend/Controllers/Controller.php:

Frontend/Controllers/HomeController.php:

Frontend/Routes/web.php:

Frontend/Views/home/welcome.blade.php:

Kết quả:

3.3. Api Module:

Tạo các file sau:

Nội dung các file như sau:

Api/Controllers/Controller.php:

Api/Controllers/V1Controller.php:

Api/Routes/v1.route.php:

Kết quả trên Postman:

 

Vậy là xong roài đó. Hy vọng giúp ích được cho các bạn.  THANK-YOU

Read More

Redis Pub/Sub – Cơ chế hoạt động – Cài đặt trên Windows

Chào các bạn. Đó giờ làm laravel, thấy cái thằng Redis chỉ được dùng làm cache nên cũng không quan tâm lắm, chỉ biết nó là dạng memory-database và lưu dữ liệu dạng key-value, hết. Hôm nay, tui lò mò tìm hiểu thì thấy Redis nó còn có một cơ chế gọi là Pub/Sub dùng để làm mấy cái ứng dụng realtime, cũng khá hay nha các bạn, nó giống như là thằng Kafka vậy dùng để làm message delivery tương tự như bài Xây dựng một Realtime Dashboard sử dụng Spark Streaming, Kafka, Nodejs và MongoDB. Bài hôm nay, chủ yếu hướng dẫn các bạn cài Redis trên Windows cũng như xem cái cơ chế Pub/Sub nó ra sau ha.

1. Cài đặt Redis trên Windows:

Nếu vào trang redis.io, các bạn không thấy cái mục download cho windows đâu, hình như là từ version 4.0, nó không còn hổ trợ cho Windows nữa hay sau đó. Nhưng không sau, các bạn vào link sau để tải về nhá: https://github.com/MicrosoftArchive/redis/releases

Chọn version là 3.2.100 (64 bit nhé), và download cái file zip như hình sau:

download xong, các bạn unzip nó ra thư mục nào cũng được, trong bài này tui unzip nó ra thư mục E:\Server\redis\3.2.100, như sau:

Các bạn chú ý 2 cái file: redis-server.exeredis-cli.exe, lát mình sẽ chạy 2 file này để làm demo.

2. Cơ chế Pub/Sub:

  • Pub: Publish, có nghĩa là một producer đẩy dữ liệu vào một channel (kênh) hay còn gọi là topic như trong Kafka
  • Sub: Subscribe có nghĩa là một consumer đăng ký nhận dữ liệu từ một channel hay topic.

Hiểu đơn giản tí, giống như xem truyền hình cáp vậy (ví dụ như SCTV), chúng ta là các consumer, đăng ký (subscribe) vào các kênh như: VTV1, VTV3, VTV6, HBO, Fox Movies…. thì SCTV chính là một producer, đẩy dữ liệu (publish) ra các kênh tương ứng đó và chúng ta chỉ nhận và xem trên TV thôi.

Như hình trên, một subscriber có thể đăng ký nhận data từ nhiều kênh nha các bạn.

3. Demo cơ chế Pub/Sub của Redis:

Do demo chỉ làm trên console, cho nên tui giả sử các bạn đều chuyển về ngay thư mục của Redis (cái thư mục mà unzip hồi nảy), như trong bài thì tui chuyển về thư mục E:\Server\redis\3.2.100 này hết nha.

Mở cmd đầu tiên lên và chạy lệnh:

Nếu nó ra như thế này có nghĩa là Redis Server đã run:

Chú ý: mặc định thì Redis nó listen ở port 6379. Để change thành port 7777, các bạn thêm tham số –port như sau:

Tiếp theo, mở 3 cái cmd lên, chạy cùng một lệnh:

Chúng ta quy định như hình trên nha, 1 PUBLISHER và 2 SUBSCRIBER

ở SUBCRIBER 1, các bạn đăng ký 2 kênh là channel-a và channel-b bằng lệnh subscribe:

ở SUBSCRIBER 2, các bạn đăng ký 1 kênh là channel-a

sau đó, ở PUBLISHER, các bạn phát một message là “Welcome to Channel A” ở channel-a bằng lệnh publish:

thì lập tức ở SUBSCRIBE 1 và SUBSCRIBE 2 sẽ hiện ra đoạn text trên:

Nếu bây giờ, ở PUBLISHER, các bạn phát một message “Welcome to Channel B” ở channel-b:

thì các bạn chỉ thấy SUBSCRIBER 1 nhận cái message đó thôi.

Đấy là cơ chế Pub/Sub của Redis, sau này có thời gian, tui sẽ làm một bài về việc dùng Redis Pub/Sub này kết hợp với Laravel Broadcasting cùng với socket.io để làm cái ứng dụng send message nho nhỏ. Vậy nhé, hẹn gặp lại.

Read More

Tạo Authentication cho module Backend và Frontend trong Laravel 5

Cũng lâu lắm rồi mới có thời gian viết bài mới. Hôm nay, tui sẽ trình bày cách để tạo authentication cho từng module Frontend và Backend. Ở đây tui sẽ mặc định là chúng ta đã tạo 2 module là Frontend và Backend nhé (các bạn có thể xem tại đây).

1. Cấu trúc thư mục:

Giả sử tui có một project tên rubik có các thư mục module BackendFrontend như sau:

2. Database để login:

Để login, giả sử tui có 2 table là usercustomer ở dưới database tương ứng để login ở BackendFrontend như sau:

Database script để tạo 2 table này:

Mỗi table có sẵn 1 account để tí nữa test login

  • alibaba@gmail.com/112233 (user)
  • aladin@gmail.com/123123 (customer)

Các bạn cần tạo model tương ứng cho 2 table trên. Tại thư mục framework/app, các bạn tạo một thư mục tên là Models, trong thư mục Models này, các bạn tạo 2 file model lần lượt là User.phpCustomer.php

Thêm namespace App\Models và file composer.json ở phần psr-4

Bậy giờ các bạn viết phần nội dung cho 2 file User.phpCustomer.php. Có 2 cách:

Một là các bạn extends cái class Illuminate\Foundation\Auth\User có sẵn của nó (xem cái file app/User.php có sẵn thì nó làm theo cách này). Hai là các bạn tự viết lại. Ở đây tui sẽ dùng 2 cách cho 2 file Models/User.phpModels/Customer.php

Models/User.php:

Models/Customer.php:

Kết nối database:

Các bạn mở file framework/.env, edit các biến sau:

Tùy theo username, password của mysql của các bạn là gì thì ghi vô cho đúng nha.

Nếu các bạn có dùng prefix khi tạo table giống tui, thì các bạn mở file config/database.php, tìm cái phần mysql trong mục connections, edit lại phần prefix:

3. Tạo Authentication Provider và Guard:

Trong Laravel 5.4, cơ chế login là dựa trên provider. Mỗi provider sẽ tương ứng với một Model. Ở đây ta có 2 Model là User và Customer dùng để login ở Backend và Frontend, vậy ta cần có 2 provider.

Để sử dụng Provider này trong Controller, Middleware hoặc View, ta cần tạo Guard. Mỗi Guard sẽ ứng với một Provider, 2 Guard khác nhau có thể dùng cùng 1 Provider.

Các bạn mở file framework/config/auth.php

Tìm mục providers, bạn sẽ thấy nó có 1 sẵn cái provider là users, kệ nó, mình thêm vào 2 cái của mình là admincustomer (đặt tên là gì cũng được, đây là key của array):

Có Provider rồi, các bạn tìm cái phần guards (cũng trong file framework/config/auth.php), nó có sẵn 2 cái guard là web và api, cũng kệ nó luôn, tạo 2 cái guard tên là admincustomer (đặt tên gì cũng được, không nhất thiết phải giống với Provider):

Các bạn chú ý là ở phần providers các bạn đặt tên là gì thì ở phần guards, trong cái phần provider thì các bạn ghi đúng cái tên đó nha.

4. Tạo trang login và AuthController:

Sau khi có Provider và Guard rồi, chúng ta làm trang login. Do phần login ở Backend và Frontend đều như nhau, chỉ khác nhau là dùng guard nào thôi, cho nên tui sẽ làm phần Backend, còn phần Frontend thì tương tự nhé

4.1. Tạo view cho trang login:

Tại thư mục Backend/Views, tạo thư mục admin.

Trong thư mục Backend/Views/admin, tạo file login.blade.php:

4.2. Tạo AuthController:

Tại thư mục Backend/Controllers, tạo file AuthController.php:

Chú ý hàm getLogin sẽ trả về giao diện là trang login

Để khi gõ url: http://localhost:8080/learning/rubik/admin/login, cái Route nó hiểu và gọi hàm getLogin của AuthController thì chúng ta phải edit lại cái file Backend/routes.php như sau:

Chú ý cái parameter của hàm group: ‘namespace’ => ‘App\Modules\Backend\Controllers’. Nếu không dùng cái parameter này thì ngay chổ phần gọi hàm của controller, các bạn phải viết đầy đủ namespace như vầy:

Giờ mà các bạn gõ url http://localhost:8080/learning/rubik/admin/login mà nó ra như sau là ok:

4.3. Xử lý phần validate email và password:

Thêm hàm postLogingetLogout vào file Backend/Controllers/AuthController.php:

Edit lại file Backend/routes.php, thêm 2 cái Route cho validate login và logout:

Giờ nếu các bạn click nút “Login” thì nó sẽ báo lỗi (1/1) TokenMismatchException, lý do là Laravel nó sẽ kiểm tra cái token mỗi khi bạn thực hiện một POST request để tránh trường hợp bị cái lỗi Flood Post.

Để thêm cái token, các bạn edit trang Backend/Views/login.blade.php như sau:

Test thôi,

Không ghi email, password gì cả, click “Login” mà nó báo lỗi là ok:

Nhập email: alibaba@gmail.com, password: 112233 mà nó vào được trang Hello Backend có cái link Logout là ok luôn.

Đó là phần login cho Backend, tương tự cho phần Frontend, các bạn gọi cái guard là customer thay cho cái guard admin. Nhớ là cái namespace của Frontend là App\Modules\Frontend\Controllers, chổ nào là Backend thì thay bằng Frontend.

Tại thư mục Frontend/Controllers, tạo file AuthController.php:

Tại thư mục Frontend/Views, tạo thư mục customer.

Trong thư mục Frontend/Views/customer, tạo file login.blade.php:

Edit lại file Frontend/routes.php, thêm 2 cái Route cho validate login và logout:

Nhập email: aladin@gmail.com, password: 123123 để test như phần Backend.

Tới đây, có một vấn đề là nếu bạn không login, thì bạn vẫn vào được trang Hello Backend. Đó là do chúng ta chưa validate được là user đã login hay chưa. Để làm việc này, chúng ta phải dùng Middleware.

5. Tạo Authentication Middleware:

Trong Laravel 5, middleware đóng vai trò là bộ lọc (filter) các request, các bạn tưởng tượng nó như các lớp của củ hành tây vậy. Các request phải “xuyên qua” hết các lớp này thì mới thực thi các callback function của Route hay Controller tương ứng. Do đó ta cũng áp dụng cơ chế này để validate xem user đã login chưa?

  • Nếu login rồi thì thôi, tiếp tục thực hiện.
  • Chưa login, cho về lại trang login

Chúng ta có thể dùng một Middleware cho 2 Module Backend và Frontend, nhưng như thế thì khó quản lý code lắm. Cho nên tui sẽ làm 2 cái Middleware tương ứng cho 2 module Backend và Frontend

5.1. Tạo Middleware cho Backend và Frontend:

Tại thư mục Modules/Backend/Middleware, tạo file AdminAuthentication.php:

Tại thư mục Modules/Frontend/Middleware, tạo file CustomerAuthentication.php:

các bạn chú ý cái namespace App\Modules\Backend\MiddlewareApp\Modules\Frontend\Middleware cũng như 2 cái guard là admincustomer nha.

Để Laravel nó chạy 2 cái Middleware này, các bạn mở file app\Http\Kernel.php, tìm cái biến array $routeMiddleware, thêm vào cuối array này 2 dòng như sau:

Cái hàm xử lý chính trong việc kiểm tra là đã login hay chưa là hàm:

nếu đã login thì thôi, tiếp tục. Còn nếu chưa login thì phần xử lý này nó nằm trong file app/Exceptions/Handler.php, hàm unauthenticated như sau:

Nếu để vậy nó không chạy đâu, các bạn sửa lại tí:

Đổi dòng

thành

Cuối cùng, để dùng 2 cái middleware admin_authcustomer_auth, thì các bạn có thể gọi hàm middleware của Route như sau:

Mở file Backend/routes.php:

thêm hàm middleware vào sau hàm get:

hoặc vào trước hàm get;

Test thôi! Logout nếu đang ở trang Hello Backend. Thử gõ url http://localhost:8080/learning/rubik/admin thì nó sẽ redirect về trang login. Làm tương tự cho file Frontend/routes.php và dùng middleware là customer_auth.

Ngoài ra, nếu cái Route của các bạn gọi hàm của Controller thì các bạn có thể gọi middleware trực tiếp trong Controller luôn và gọi ở hàm __construct(), không cần gọi hàm middleware của Route như trên nữa.

Ví dụ, tui có DashboardController trong Backend:

Trên đây là những gì tui biết về phần Authentication trong Laravel 5, tuy bài viết hơi dài, nhưng các phần đều có liên quan với nhau. Hi vọng là bài này sẽ giúp giải đáp phần nào thắc mắc của các bạn về phần Authentication.  THANK-YOU

Read More

Tạo module Backend và Frontend trong Laravel 5

Xem bài viết version 2

Lúc trước trong series “Xây dựng website QUIZ“, tui có hướng dẫn tạo module. Hôm nay tui sẽ viết lại cái phần tạo module cho Laravel 5.4 thành một bài dạng tips để cho mọi người tiện tham khảo. Bắt đầu nào!

1. Tạo project và các thư mục:

Giả sử, thư mục WEB_ROOT cho project này hiện lại là E:\Server\www\learning:

Tại thư mục WEB_ROOT:

Sau khi tạo xong (không nhất thiết là đặt cái tên là framework nha các bạn, đặt tên gì cũng được), các bạn sẽ có cây thư mục như sau:

Copy các file và thư mục trong thư mục framework/public ra ngoài thư mục rubik như sau:

Mở file rubik/index.php lên,  tim đến 2 dòng sau:

và thay dấu “..” thành tên thư mục “framework” như sau:

Đó là phần Frontend, tiếp theo cũng trong thư mục rubik, tạo thư mục tên là admin cho phần Backend và cũng copy tất cả các file và thư mục trong framework/public vào thư mục admin này:

Mở file admin/index.php lên, tìm 2 dòng sau:

và edit lại như sau:

Do chúng ta copy các file này từ thư mục framework/public ra bên ngoài, cho nên mục đích của việc edit 2 file index.php này là để dẫn lại đường dẫn cho đúng.

Tiếp, chúng ta phải override lại cái hàm public_path(), lý do là ta đã sửa cái thư mục public mặc định thành thư mục gốc rồi. Mở file app\Providers\AppServiceProvider.php, thêm như sau:

Khi gọi hàm helper puclic_path(), các bạn sẽ thấy nó trả về cái thư mục gốc chứa file index.php.

Nếu thử gõ 2 cái url: http://localhost:8080/learning/rubik và http://localhost:8080/learning/rubik/admin mà hiện ra như sau là ổn:

Sau khi tạo xong, các bạn nên xóa cái thư mục framework/public đi, hoặc khi upload source code lên host thì không cần upload thư mục framework/public này.

2. Tạo module Backend và Frontend:

Trước tiên, tại thư mục framework/app, chúng ta tạo thư mục Modules với các thư mục con và file tương ứng như sau:

Sau đó, tại thư mục framework/config, chúng ta tao một file tên là module.php:

Nội dung cho file config/module.php như sau:

Mục đích của việc tạo file config/module.php là để kiểm tra cái url khi nào là vào frontend hoặc backend để điều hướng xửa lý vào các thư mục chứa code tương ứng trong Modules/Backend hay Modules/Frontend.

Để làm việc này, ta phải viết code cho file Modules/ModuleServiceProvider.php như sau:

Để Laravel nó load được cái file ModuleServiceProvider.php này, các bạn mở file framework/config/app.php lên, tìm đến phần array providers (dòng 138), và thêm vào cuối array này dòng App\Modules\ModuleServiceProvider::class

Để cho chắc chắn rằng Laravel 5 nó hiểu cái namespace App\Modules, chúng ta mở file framework/composer.json, tìm đến mục psr-4 nằm trong mục autoload:

Thêm như sau:

3. Xử lý route url cho từng module:

Phần trước, chúng ta đã tạo file routes.php tương ứng cho từng module Backend và Frontend. Bây giờ, trong mỗi file routes.php này, chúng ta sẽ tạo các Route để xem cái ModuleServiceProvider.php nó có thực hiện đúng hay không nha.

Nếu url là http://localhost:8080/learning/rubik thì sẽ in ra câu “Hello Frontend”

Nếu url là http://localhost:8080/learning/rubik/admin thì sẽ in ra câu “Hello Backend”

Nhưng trước hết là chúng ta phải bỏ cái Route xử lý hiển thị cái view mặc định hiển thị chữ “Laravel” to đùng như ở trên đã. Các bạn mở file framework/routes/web.php lên:

và xóa hoặc comment lại cái Route xử lý trang welcome:

Xong, tiếp theo là code cho 2 file routes.php nha

Backend/routes.php

Frontend/routes.php

Thử nào:

  • Url là http://localhost:8080/learning/rubik thì sẽ in ra câu “Hello Frontend”.
  • Url là http://localhost:8080/learning/rubik/admin thì sẽ in ra câu “Hello Backend”.

Nếu hiển thị đúng như vậy thì cái file Modules/ModuleServiceProvider.php nó đã được load và xử đúng. Tui làm được thì các bạn cũng làm được.  THANK-YOU

 

Read More