Hướng dẫn loa token to php - Oh và tỉnh và php

Chào các bạn, mình đã trở lại rồi đây. Ở bài viết lần trước, mình đã giới thiệu cho các bạn về Json Web Token và cách thức hoạt động của nó. Các bạn có thể xem lại ở đây để hiểu rõ hơn về phần lý thuyết trước nhé.ở đây để hiểu rõ hơn về phần lý thuyết trước nhé.

Nội dung chính ShowShow

  • 1. Giới thiệu
  • 2. Cài đặt Project
  • 3. Cài đặt và cấu hình package JWT Authentication
  • 4. Thiết lập model User
  • 5. Cấu hình Auth Guard
  • 6. Tạo authentication controller
  • 6. Tạo các authentication routes
  • 6. Test các api vừa tạo bằng postman
  • 7. Kết luận

Trong bài viết này, mình sẽ hướng dẫn các bạn viết API phục vụ cho việc đăng ký, đăng nhập với JWT Authentication (Laravel 8). Mình sẽ cùng nhau tìm hiểu cách bảo vệ các RESTful APIs của chúng ta bằng việc sử dụng thư viện tymondesigns/jwt-auth.tymondesigns/jwt-auth.

1. Giới thiệu

2. Cài đặt Project

3. Cài đặt và cấu hình package JWT Authentication

2. Cài đặt Project

3. Cài đặt và cấu hình package JWT Authentication
Cài đặt thông qua composer:
$ composer create-project laravel/laravel jwt-auth

4. Thiết lập model User
$ laravel new jwt-auth

5. Cấu hình Auth Guard

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=jwt
DB_USERNAME=root
DB_PASSWORD=MẬT_KHẨU_MYSQL

6. Tạo authentication controller

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
0

3. Cài đặt và cấu hình package JWT Authentication

4. Thiết lập model User

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
1

5. Cấu hình Auth Guardcomposer require tymon/jwt-auth thì nó sẽ tải bản 0.5.12 và bạn sẽ gặp lỗi này:

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.

6. Tạo authentication controller

'providers' => [
    ....
    ....
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],

6. Tạo các authentication routes

'aliases' => [
    ....
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
    ....
],

6. Test các api vừa tạo bằng postman

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
2

7. Kết luận

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
3

Trong bài viết này, mình sẽ hướng dẫn các bạn viết API phục vụ cho việc đăng ký, đăng nhập với JWT Authentication (Laravel 8). Mình sẽ cùng nhau tìm hiểu cách bảo vệ các RESTful APIs của chúng ta bằng việc sử dụng thư viện tymondesigns/jwt-auth.

    - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
    - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
4

4. Thiết lập model User

5. Cấu hình Auth Guard

  •     - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
        - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
    
    5
  •     - Root composer.json requires tymon/jwt-auth ^0.5.12 -> satisfiable by tymon/jwt-auth[0.5.12].
        - tymon/jwt-auth 0.5.12 requires illuminate/support ~5.0 -> found illuminate/support[v5.0.0, ..., 5.8.x-dev] but these were not loaded, likely because it conflicts with another require.
    
    6

6. Tạo authentication controller



namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use HasFactory, 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',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier() {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims() {
        return [];
    }
}

5. Cấu hình Auth Guard

6. Tạo authentication controllerconfig/auth.php như sau:



return [

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],


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

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

6. Tạo authentication controller

6. Tạo các authentication routes

6. Test các api vừa tạo bằng postman



namespace App\Http\Controllers;
use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Validator;


class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct() {
        $this->middleware('auth:api', ['except' => ['login', 'register']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request){
    	$validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required|string|min:6',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        if (! $token = auth()->attempt($validator->validated())) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->createNewToken($token);
    }

    /**
     * Register a User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request) {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|between:2,100',
            'email' => 'required|string|email|max:100|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ]);

        if($validator->fails()){
            return response()->json($validator->errors()->toJson(), 400);
        }

        $user = User::create(array_merge(
                    $validator->validated(),
                    ['password' => bcrypt($request->password)]
                ));

        return response()->json([
            'message' => 'User successfully registered',
            'user' => $user
        ], 201);
    }


    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout() {
        auth()->logout();

        return response()->json(['message' => 'User successfully signed out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh() {
        return $this->createNewToken(auth()->refresh());
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function userProfile() {
        return response()->json(auth()->user());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function createNewToken($token){
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60,
            'user' => auth()->user()
        ]);
    }

    public function changePassWord(Request $request) {
        $validator = Validator::make($request->all(), [
            'old_password' => 'required|string|min:6',
            'new_password' => 'required|string|confirmed|min:6',
        ]);

        if($validator->fails()){
            return response()->json($validator->errors()->toJson(), 400);
        }
        $userId = auth()->user()->id;

        $user = User::where('id', $userId)->update(
                    ['password' => bcrypt($request->new_password)]
                );

        return response()->json([
            'message' => 'User successfully changed password',
            'user' => $user,
        ], 201);
    }
}
  • 7. Kết luận
  • Trong bài viết này, mình sẽ hướng dẫn các bạn viết API phục vụ cho việc đăng ký, đăng nhập với JWT Authentication (Laravel 8). Mình sẽ cùng nhau tìm hiểu cách bảo vệ các RESTful APIs của chúng ta bằng việc sử dụng thư viện tymondesigns/jwt-auth.
  • Tại sao lại cần phải bảo mật API? Thật đơn giản, nó cũng giống như việc bạn đi vào một khách sạn vậy, muốn vào một căn phòng nào đó của khách sạn thì trước hết bạn phải qua lễ tân. Tại đây lễ tân sẽ tiến hành kiểm tra chứng mình thư, thẻ căn cước,... để xác thực được danh tính của bạn. Thì API cũng như vậy, trước ghi đáp ứng request mà bạn gửi lên, server cũng cần phải kiểm tra "chứng minh thư" của bạn để xác thực rõ xem bạn là ai, bạn đến từ đâu
  • Trong bài viết này mình xin giới thiệu đến các bạn một cô lê tân vô cùng xinh đẹp, khá lớn tuổi nhưng làm việc vẫn rất hiệu quả và ổn định - JWT (Json Web Token)
  • Đầu tiên, ta hãy cùng nhau tạo ra 1 project laravel nhé. Cài đặt thông qua composer: $ composer create-project laravel/laravel jwt-auth
  • Phương thức userProfile() hiển thị dữ liệu của người dùng đã đăng nhập.

6. Tạo các authentication routes

Mở file routes/api.php và thêm vào các route sau:routes/api.php và thêm vào các route sau:

Route::group([
    'middleware' => 'api',
    'prefix' => 'auth'

], function ($router) {
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::post('/refresh', [AuthController::class, 'refresh']);
    Route::get('/user-profile', [AuthController::class, 'userProfile']);
    Route::post('/change-pass', [AuthController::class, 'changePassWord']);    
});

6. Test các api vừa tạo bằng postman

  • Register API Kết quả trả về:

    Kết quả trả về:

  • Login API Kết quả trả về: Như các bạn đã thấy, khi login thành công, server sẽ trả về một chuỗi access_token, phía client có thể lưu chuỗi token này ở local storage, cookie,... Và sau đó mình sẽ sử dụng chuỗi token này để gửi request đến các API của server. Thế tại sao khi mình gửi request đến API register và login thì không cần gửi kèm access token, mà server vẫn phản hồi ok vậy nhỉ? Chắc bạn bạn còn nhớ ở phần middleware, mình đã loại trừ hai hàm login và register khỏi middleware auth:api. Còn với các API khác, mọi request của user gửi lên đều phải đi qua middleware này, nó sẽ check xem bạn có gửi chuỗi token hợp lệ hay không thì mới cho đi qua đó!!!

    Kết quả trả về:

    Như các bạn đã thấy, khi login thành công, server sẽ trả về một chuỗi access_token, phía client có thể lưu chuỗi token này ở local storage, cookie,... Và sau đó mình sẽ sử dụng chuỗi token này để gửi request đến các API của server. Thế tại sao khi mình gửi request đến API register và login thì không cần gửi kèm access token, mà server vẫn phản hồi ok vậy nhỉ? Chắc bạn bạn còn nhớ ở phần middleware, mình đã loại trừ hai hàm login và register khỏi middleware auth:api. Còn với các API khác, mọi request của user gửi lên đều phải đi qua middleware này, nó sẽ check xem bạn có gửi chuỗi token hợp lệ hay không thì mới cho đi qua đó!!!
  • Hãy nhớ thêm header field "Authorization: Bearer Token" cho các API User Profile, Token Refresh, Change Password và Logout.

  • Logout API

  • User Profile API

  • Token Refresh API Như vậy một chuỗi token mới được sinh ra, và bạn sẽ không thể dùng chuỗi token cũ để gửi request lên được, vì đơn giản nó đã hết hạn rồi

    Như vậy một chuỗi token mới được sinh ra, và bạn sẽ không thể dùng chuỗi token cũ để gửi request lên được, vì đơn giản nó đã hết hạn rồi

  • Change Password API

7. Kết luận

Bài viết khá dài dòng nhỉ, mình viết hơi vội mong mọi người thông cảm ạ. Ở bài viết lần sau, mình sẽ hướng dẫn mọi người tự tạo ra một chuỗi token chay để hiểu rõ hơn về bản chất của JWT. Cảm ơn mọi người đã đọc bài viết ạ


Và đây là link github của phần demo JWT mình đã giới thiệu bên trên: https://github.com/vuminhhieu1311/jwt-auth