Skip to content

2. Login

dungda-0794 edited this page Mar 16, 2023 · 18 revisions

Note: Validation & logic login inside service

Features

  • Validate attributes
  • Callback use model
  • Generate JWT token
  • Session Login

Example

POST /login
  • Parameters
Request Field Field Type Required Field Desc
username string true username for user
password string true password for user
  • Responses
Response Field Field Type Required Field Desc
refresh_token string true refresh_token for user get access_token
access_token string true access_token for user logged
token_type string true token_type for user logged
expires_at integer true expires_at for user logged
curl -X 'POST' \
  'http://localhost/api/login' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "user1234",
  "password": "passwordRequired@123"
}'
{
  "refresh_token": "eyJ0eXAiOiJKV1QiLC...",
  "access_token": "eyJ0eXAiOiJKV1...",
  "token_type": "bearer",
  "expires_at": 1676281826
}

Usage

Usage with JWT

Make route function the following:

# routes/api.php
Route::post('login', 'AuthController@login');

Make login function the following:

# App\Http\Controllers\AuthController
...
use SunAsterisk\Auth\Contracts\AuthJWTInterface;
...
protected AuthJWTInterface $service;

public function __construct(AuthJWTInterface $service)
{
    $this->service = $service;
}

public function login(Request $request)
{
    $params = $request->only(['username', 'password']);
    // use service package
    $rs = $this->service->login($params, [], function ($entity) {
        return $entity->only(['id', 'email', 'username']);
    });

    return response()->json($rs['auth']);
}

Usage with Session

Make route function the following:

# routes/web.php
Route::get('login', [App\Http\Controllers\AuthController::class, 'showLoginForm']);
Route::post('login', [App\Http\Controllers\AuthController::class, 'login'])->name('login');

Make login function the following:

...
use SunAsterisk\Auth\Contracts\AuthSessionInterface;
...
protected AuthSessionInterface $service;

public function __construct(AuthSessionInterface $service)
{
    $this->service = $service;
}

public function showLoginForm()
{
    return view('auth.login');
}

public function login(Request $request)
{
    $params = $request->only(['email', 'password']);

    $this->service->login($params, [], function ($entity) {
        //
    });

    return redirect()->intended('home');
}

Workflow

Sun_ Auth _ Architecture Design-Login (1)

Explain

Interface

/**
* [login]
* @param  array         $credentials [The user's attributes for authentication.]
* @param  array|null    $attributes  [The attributes use for query.]
* @param  callable|null $callback    [The callback function has the entity model.]
* @return [array]
*/
public function login(array $credentials = [], ?array $attributes = [], ?callable $callback = null): array;

1. Validator

# SunAsterisk\Auth\Services\AuthJWTService;
public function login(array $credentials = [], ?array $attributes = [], ?callable $callback = null): array
{
  $this->loginValidator($credentials)->validate();
  ...
}
...
protected function loginValidator(array $data)
{
    return Validator::make($data, [
        $this->username()  => 'required',
        $this->passwd() => 'required',
    ]);
}

2. Find item by attribute

# SunAsterisk\Auth\Services\AuthJWTService;
public function login(array $credentials = [], ?array $attributes = [], ?callable $callback = null): array
{
    ...
    $item = $this->repository->findByAttribute($attributes);
}

3. Compare hash password

# SunAsterisk\Auth\Services\AuthJWTService;
public function login(array $credentials = [], ?array $attributes = [], ?callable $callback = null): array
{
    ...
    if (! $item || ! Hash::check(Arr::get($credentials, $this->passwd()), $item->{$this->passwd()})) {
        throw ValidationException::withMessages([
            'message' => $this->getFailedLoginMessage(),
        ]);
    }
}

4. Generate accessToken & refreshToken from jwt

# SunAsterisk\Auth\Services\AuthJWTService;
public function login(array $credentials = [], ?array $attributes = [], ?callable $callback = null): array
{
    ...
    $payload = $this->jwt->make($itemArr)->toArray();
    $payloadRefresh = $this->jwt->make($itemArr, true)->toArray();

    $jwt = $this->jwt->encode($payload);
    $refresh = $this->jwt->encode($payloadRefresh, true);
}

Method login will return an array

'item' => $itemArr,
'auth' => [
    'refresh_token' => 'eyJhbGciOiJIUzI1NiIsIn...',
    'access_token' => 'eyJiwibmFtZSI6Ikpva...',
    'token_type' => 'bearer',
    'expires_at' => 1675742447,
],
  • $itemArr is array of object user model. We can custom by callback function as follows
# App\Http\Controllers\AuthController
$rs = $this->service->login($params, [], function ($entity) {
    // Custom $itemArr
    return $entity->only(['id', 'email', 'username']);
});

BTW: Also we can change the sql query for the login flow as follows

# App\Http\Controllers\AuthController
$rs = $this->service->login(
    $params,
    [
        'username' => $params['username'],
        'is_active' => true, // custom query attributes
    ],
    function ($entity) {
        return $entity->only(['id', 'email', 'username']);
    },
);

Clone this wiki locally