07/09/2018, 17:45

Mình đã làm bể cá thông minh như thế nào - Wemos authenticate qua laravel (phần 4.1 - tạo server)

Xin chào các bạn! Đã lâu lắm rồi mình mới có thể quay trở lại viết bài về series làm bể cá thông minh. Dạo này mình cũng hơi bận chút nên không thể viết những bài viết thường xuyên được. :) Hôm nay mình xin chia sẻ về cách authenticate (xác thực thiết bị) cho Wemos bằng ứng dụng laravel. Và ai ...

Xin chào các bạn!
Đã lâu lắm rồi mình mới có thể quay trở lại viết bài về series làm bể cá thông minh.
Dạo này mình cũng hơi bận chút nên không thể viết những bài viết thường xuyên được. :)
Hôm nay mình xin chia sẻ về cách authenticate (xác thực thiết bị) cho Wemos bằng ứng dụng laravel.
Và ai chắc hẳn ai cũng biết Authentication là quá trình xác định và xác nhận danh tính của một khách truy cập vào một ứng dụng - ở đây là Wemos.
Như các bài trước mình giới thiệu thì wemos kết nối trực tiếp luôn và gửi dữ liệu lên server được luôn mà không cần một sự xác thực danh tính gì cả.
Như vậy thật sự là rất nguy hiểm. Ai cũng có thể gửi dữ liệu về server. Ai cũng có thể điều khiển thiết bị cho cá ăn của bạn.

Giả sử anh hàng xóm sang chơi nhà bạn tình cờ nhìn thấy cách bạn kết nối biết link bạn kết nối đến server và biết cấu trúc request bạn gửi để cho cá ăn.
Vào một ngày đẹp trời bạn không có nhà anh ý truy cập vào server, cho cá ăn tùm lum thì lúc đó hậu quả là vô cùng to lớn.
Vì thế nên chúng ta phải làm phần xác thực cho các kết nối đến server để chắc chắn rằng chỉ có bạn mới có thể điều khiển hệ thống của mình. Và chỉ có Wemos được gắn với thiết bị của mình mới có thể gửi lên các giá trị cần thiết.

Không để các bạn chờ lâu chúng ta cùng đi vào chủ đề ngày hôm nay nào!

Bài viết này mình sử dụng:

  • Framework laravel
  • Nodejs socket.io
  • Thư viện jwt-auth để tạo jwt token.
  • Thư viện socketio-jwt để parse jwt token giúp việc xác nhận người dùng

Chúng ta phải thực hiện 2 việc:

  • Việc thứ nhất là cài đặt 1 server laravel để wemos hoặc người dùng đăng nhập vào hệ thống.
  • Việc thứ hai là cài đặt nodejs dùng socket.io để làm server điều khiển thiết bị, thu thập dữ liệu.

Sơ đồ tổng quan hệ thống của mình sẽ như sau:

Người dùng sau khi đăng nhập xong sẽ được server laravel gửi cho 1 cái token để xác thực khi kết nối vào hệ thống điều khiển.
Và tất nhiên nếu kết nối thành công thì người dùng sẽ được phép điều khiển hệ thống. Và thiết bị cũng vậy. Muốn kết nối vào hệ thống cũng đều phải qua bước đăng nhập vào server laravel và xác thực, kết nối với server điều khiển.

Có bạn hỏi mình sao không làm luôn phần đăng nhập bằng nodejs? Bày đặt cài thêm cái laravel vào làm gì.
Lý do đơn giản là khi ta cài với laravel thì sẽ làm được trang web hoàn chỉnh đơn giản hơn, dễ dàng hơn, bảo mật hơn, tích hợp module nhanh chóng và nhiều hơn thế nữa.
Giả sử sau này bạn muốn điều khiển và theo dõi tất cả các thiết bị trong nhà chẳng hạn thì ta có thể làm được trang điều khiển như vậy.
Và một điều quan trọng nữa là laravel là thế mạnh của mình và tất nhiên phải tận dụng thế mạnh để làm mọi việc đơn giản hơn đúng không nào.

Bây giờ chúng ta sẽ cùng thực hiện từng bước một nhé!

Chúng ta sẽ sử dụng code phần 3 để viết thêm cho phần 4 này nhé. Bạn có thể đọc lại phần 3 tại đây

Cài đặt laravel master

Việc cài đặt server laravel rất đơn giản:

  • B1: Tải file code master của laravel tại đây về và giải nén.
  • B2: Chạy composer install. Nếu bạn chưa có composer thì hãy cài vào nhé. Quá trình chạy sẽ hơi lâu. Hãy kiên nhẫn chờ đợi và thưởng thức 1 ly nước lọc để lấy năng lượng cài đặt tiếp nhé.
  • B3: Tạo 1 database, copy file .env.example và đổi tên thành .env và cấu hình các biến database vào đấy.
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=iot_server
DB_USERNAME=root
DB_PASSWORD=1234567890

Cấp quyền cho thư mục storage và cache

chmod 777 -R storage
chmod 777 -R bootstrap/cache

Thế là chúng ta đã cài xong laravel master.
Bây giờ thì tải code server ở phần 3 của mình về và gộp nó vào với code của laravel.
Mục đích của phần này là mình sẽ sử dụng 1 thư mục duy nhất, sử dụng chung file .env để cho nó chung JWT_SECRET.
Các bạn chỉ cần cho nó chung key JWT-SECRET là được không nhất thiết phải gộp vào nhưng ở đây mình sẽ gộp để cho code đẹp và gọn gàng hơn.

Trước hết cần phải cài thư viện jwt-auth đã.

Cài đặt jwt-auth

Thêm dòng "tymon/jwt-auth": "~1.0.0-rc.1" vào file composer.json
Chạy lệnh

composer update

Thêm các biến vào file config/app.php

  • Thêm provider vào mảng providers
'providers' => [
    /*...........*/
    TymonJWTAuthProvidersLaravelServiceProvider::class,
]

Thêm aliase vào mảng aliases

'aliases' => [
    /*...........*/
   'JWTAuth' => TymonJWTAuthFacadesJWTAuth::class,
]

Publish file config mặc định của jwt-auth. Bạn có thể sửa các thông số cài đặt ở đây cho phù hợp. Mình sẽ không không sửa gì. Sử dụng cái cài đặt mặc định luôn.

php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"

Tạo JWT_SECRET sử dụng lệnh php artisan jwt:secret

Xong quá trình cài thư viện jwt-auth bây giờ chúng ta sẽ đi vào viết các hàm phục vụ cho việc đăng nhập, đăng xuất cho người dùng và thiết bị kết nối đến.

Tạo database

Chúng ta có 2 loại người dùng nên dùng 2 bảng users và devices
Các bạn hãy xóa hết file trong thư mục database/migrations' đi. Sau đó chạy lệnhphp artisan make:migration create_database` rồi thêm vào hàm up() và down() như sau:

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('devices', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('category_id')->unsigned();
            $table->string('name');
            $table->string('identify_code')->unique();
            $table->string('password');
            $table->boolean('is_actived')->default(true);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
        Schema::dropIfExists('devices');
    }

Chạy lệnh php artisan migrate để laravel tạo các bảng vào database.

Tiếp đến là tạo các Models tương ứng. Các bạn để các models vào thư mục app/Models cho gọn.

/* app/Models/User.php */
<?php

namespace App;

use IlluminateNotificationsNotifiable;
use IlluminateFoundationAuthUser as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}
/* app/Models/Device.php */
<?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;
use IlluminateAuthAuthenticatable;
use IlluminateFoundationAuthAccessAuthorizable;
use IlluminateContractsAuthAuthenticatable as AuthenticatableContract;
use IlluminateContractsAuthAccessAuthorizable as AuthorizableContract;
use AppModelsTraitsActiveable;
use AppModelsTraitsFilterable;

class Device extends Model implements
    AuthenticatableContract,
    AuthorizableContract
{
    use Authenticatable, Authorizable, Activeable, Filterable;

    protected $fillable = [
        'identify_code', 'name', 'password', 'is_actived',
    ];

    protected $table = 'devices';

    protected $hidden = [
        'password', 'remember_token',
    ];
}

Config laravel guard

laravel guard là cách gọi của laravel để phân loại người dùng.
Ở đâu chúng ta có 2 loại đó là thiết bị và người dùng đăng nhập vào hệ thống.
Do đó phải tạo 2 guard tương ứng.
Cách tạo như sau:

Đầu tiên config trong file config/auth.php

    'defaults' => [
        'guard' => 'web',
    ],
    
    'guards' => [
        'user' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'device' => [
            'driver' => 'session',
            'provider' => 'devices',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsUser::class,
        ],

        'devices' => [
            'driver' => 'eloquent',
            'model' => AppModelsDevice::class,
        ],
    ],

    'passwords' => [
    ],

Như vậy là chúng ta đã cấu hình cài đặt cơ bản, tạo database và config phân quyền người dùng. Bạn có thể tham khảo code của mình tại đây.

Phần tiếp theo chúng ta sẽ viết tiếp server. Thiết lập đăng nhập và authenticate ở phía người dùng.
Và phần cuối cùng sẽ tìm hiểu việc đăng nhập, kết nối socket giữa wemos với server mình vừa tạo.
Cuối này sẽ đi sâu vào lập trình cho wemos gửi gói tin http, giữ trạng thái đăng nhập, kết nối socket.io và xác thực sẽ hứa hẹn đầy hấp dẫn.
Các bạn hãy chờ để đón đọc nhé.

Cảm ơn các bạn đã đọc bài viết của mình.

Nếu thấy hay thì hãy share cho bạn bè cùng đọc.

Nếu có bất kì thắc mắc nào hãy comment bên dưới hoặc đặt câu hỏi ở link dưới nhé.

Chúc các bạn luôn thành công.

0