PHP code example of sun-asterisk / php-auth

1. Go to this page and download the library: Download sun-asterisk/php-auth library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

sun-asterisk / php-auth example snippets


public function register(Request $request)
{
    $rules = [];
    $fields = $request->only(['username', 'password', 'email']);

    $result = $this->service->register($fields, $rules, function ($entity) {
        return $entity->only(['id', 'email', 'username']);
    });

    return response()->json($result);
}

public function showRegistrationForm()
{
    return view('auth.register');
}

public function register(Request $request)
{
    $fields = $request->only(['username', 'password', 'email']);
    $fields['name'] = $fields['username'];

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

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

$this->service->register($fields, [], function ($entity) {
        //
    }, true);

# App\Http\Controllers\AuthController
public function postForgotPassword(Request $request)
{
    $email = $request->email;
    $status = $this->service->postForgotPassword($email, function ($token, $user) {
        // Use send mail from framework
        sendEmail($user, $token);
    });

    return response()->json([
        'ok' => $status,
        'type' => 'forgotPassword',
    ]);
}

public function confirm(Request $request)
{
   $token = $request->token;
   $status = $this->service->verifyToken($token);

   return response()->json([
       'ok' => $status,
   ]);
}

# App\Http\Controllers\AuthController
public function postNewPassword(Request $request)
{
   $params = $request->only(['password', 'token']);
   $status = $this->service->changePassword($params, null, function ($user, &$attr) {
       // Update attr
   });

   return response()->json([
       'ok' => $status,
       'type' => 'newPassword',
   ]);
}

# App\Http\Controllers\AuthController;
public function refresh(Request $request)
{
    $token = $request->refresh_token;

    $rs = $this->service->refresh($token);

    return response()->json($rs);
}

# config/services.php
...
'google' => [    
  'client_id' => env('GOOGLE_CLIENT_ID'),  
  'client_secret' => env('GOOGLE_CLIENT_SECRET'),  
  'redirect' => env('GOOGLE_REDIRECT_URI'),
],

# config/sun-asterisk.php
...
/*
|---------------------------------------------------------
| use Socialite Providers for social login
|---------------------------------------------------------
|
| Default false
|
*/
'enabled_social' => true,

# routes/web.php
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use SunAsterisk\Auth\Contracts\AuthSocialInterface;
...

// Redirect Endpoint
Route::get('social/{provider}/redirect', function (Request $request) {
    $provider = $request->provider;
    // use service from package
    return app(AuthSocialInterface::class)->socialSignIn($provider);
});

// Callback Endpoint
Route::get('social/{provider}/callback', function (Request $request) {
    $provider = $request->provider;
    // use service from package
    $socialUser = app(AuthSocialInterface::class)->socialCallback($provider);

    $user = \App\Models\User::updateOrCreate([
        'social_id' => $socialUser->id,
        'social_type' => $provider,
    ], [
        'name' => $socialUser->name,
        'email' => $socialUser->email,
        'avatar' => $socialUser->avatar,
    ]);

    Auth::login($user);

    return redirect('/dashboard');
});

/**
* [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;

# 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()  => '

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


# 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(),
        ]);
    }
}

# 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);

    $this->tokenMapper->add($payload, $refresh);
}

'item' => $itemArr,
'auth' => [
    'refresh_token' => 'eyJhbGciOiJIUzI1NiIsIn...',
    'access_token' => 'eyJiwibmFtZSI6Ikpva...',
    'token_type' => 'bearer',
    'expires_at' => 1675742447,
],

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

# 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']);
    },
);

# SunAsterisk\Auth\SunServiceProvider
/**
 * Extend Laravel's Auth.
 *
 * @return void
 */
protected function extendAuthGuard(): void
{
    $this->app['auth']->extend('sun', function ($app, $name, array $config) {
    $storage = $app->make(Providers\Storage::class);
    $blackList = new SunBlacklist($storage);
    $jwt = new SunJWT($blackList, $app->config->get('sun-asterisk.auth'));
    $tokenMapper = new SunTokenMapper($storage);

    $guard = new SunGuard(
        $jwt,
        $app['auth']->createUserProvider($config['provider']),
        $app['request'],
        $tokenMapper
    );
    app()->refresh('request', $guard, 'setRequest');

    return $guard;
});
}

# SunAsterisk\Auth\SunGuard
/**
 * Logout the user, thus invalidating the token.
 *
 * @return void
 */
public function logout()
{
    try {
        $token = $this->request->bearerToken();
        $rawToken = $this->jwt->decode($token);
        $refreshToken = $this->tokenMapper->pullRefreshToken($rawToken['jti']);

        $this->jwt->invalidate($token);
        if ($refreshToken) {
            $this->jwt->invalidate($refreshToken, true);
        }
    } catch (\Exception $e) {
        throw new Exceptions\JWTException($e->getMessage());
    }
}

# SunAsterisk\Auth\SunJWT
public function invalidate(string $token, bool $isRefresh = false): bool
{
    if (! $this->blackList) {
        throw new Exceptions\JWTException('You must have the blacklist enabled to invalidate a token.');
    }

    $payload = $this->decode($token, $isRefresh, false);

    return $this->blackList->add($payload);
}

/**
* [register]
* @param  array         $fields    [The user's attributes for register.]
* @param  array         $rules     [The rules for register validate.]
* @param  callable|null $callback  [The callback function has the entity model.]
* @return [array]
*/
public function register(array $params = [], array $rules = [], callable $callback = null): array;

# SunAsterisk\Auth\Services\AuthJWTService;
public function register(array $params = [], array $rules = [], callable $callback = null): array
{
    if (empty($rules)) {
        $rules = [
            'username' => ['set($params['email'])) {
            $rules['email'] = ['

# SunAsterisk\Auth\Services\AuthJWTService;
public function register(array $params = [], array $rules = [], callable $callback = null): array
{
    ...
    $params[$this->passwd()] = Hash::make($params[$this->passwd()]);
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function register(array $params = [], array $rules = [], callable $callback = null): array
{
    ...
    $item = $this->repository->create($params);
}

# App\Http\Controllers\AuthController
public function register(Request $request)
{
    $fields = $request->only(['password', 'email']);
    // customer validate
    $rules = [
        'email' => '

/**
* [postForgotPassword]             
* @param  string        $email     [The user's email for receive token]
* @param  callable|null $callback  [The callback function response token & entity model.]
* @return [bool]
*/
public function postForgotPassword(string $email, callable $callback = null): bool;

/**
* [verifyForgotPasswordToken]
* @param  string        $token     [The token from user's email]
* @param  callable|null $callback  [The callback function has the token & entity model.]
* @return [bool]
*/
public function verifyToken(string $token, callable $callback = null): bool;

/**
* [changePassword]
* @param  array         $params    [The params for change password (passwd | ?old_passwd | ?token)]
* @param  int|null      $userId    [The user's id when user authenticate.]
* @param  callable|null $callback  [The callback function have the entity model & pointer of users's attributes.]
* @return [bool]
*/
public function changePassword(array $params = [], ?int $userId = null, callable $callback = null): bool;

# SunAsterisk\Auth\Services\AuthJWTService;
public function postForgotPassword(string $email, callable $callback = null): bool
{
   ...
   // Validate Email
   Validator::make(['email' => $email], [
       'email' => ['nvalid.',
       ]);
   }
   ...
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function postForgotPassword(string $email, callable $callback = null): bool
{
   ...
   $obj = [
       'id' => $item->id,
       'created_at' => Carbon::now()->timestamp,
   ];

   $token = Crypt::encryptString(json_encode($obj));
   ...
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function verifyToken(string $token, callable $callback = null): bool
{
     ...
     $objStr = Crypt::decryptString($token);
     $obj = json_decode($objStr, true);
     ...
     $diffSeconds = Carbon::now()->diffInSeconds(Carbon::createFromTimestamp($obj['created_at']));

     if ($diffSeconds >= $this->config['token_expires'] * 60) {
          throw new AuthException('Token is invalid!');
     }
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function changePassword(array $params = [], ?int $userId = null, callable $callback = null): bool
{
   ...
   $user = null;
   $attr = [];

   // For usecase forgot password
   if (isset($params['token'])) {
       $this->verifyToken($params['token'], function ($entity) use (&$user) {
           $user = $entity;
       });
   }
   ...

   if ($user) {
       $attr[$this->passwd()] = Hash::make($params[$this->passwd()]);
       ...

       $this->repository->updateById($user->id, $attr);
   }
   ...
}

/**
* [refresh]
* @param  string $refreshToken     [refresh_token for user get access_token]
* @param  callable|null $callback  [The callback function has the entity model.]
* @return [array]
*/
public function refresh(?string $refreshToken, callable $callback = null): array;

# SunAsterisk\Auth\Services\AuthJWTService;
public function refresh(?string $refreshToken, callable $callback = null): array
{
    ...
    $payload = $this->jwt->decode($refreshToken ?: '', true);
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function refresh(?string $refreshToken, callable $callback = null): array
{
    ...
    if (Carbon::createFromTimestamp($payload['exp'])->lte(Carbon::now())) {
        throw new InvalidArgumentException('The RefreshToken is invalid.');
    }
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function refresh(?string $refreshToken, callable $callback = null): array
{
    ...
    $item = $this->repository->findById($sub?->id);
    if (!$item) {
        throw new InvalidArgumentException('The RefreshToken is invalid.');
    }
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function revoke(array $keys = []): bool
    {
        try {
            return $this->jwt->revoke($keys);
        } catch (\Exception $e) {
            throw new Exceptions\JWTException('Revoke token is wrong.');
        }
    }


# SunAsterisk\Auth\Services\AuthJWTService;
public function refresh(?string $refreshToken, callable $callback = null): array
{
    ...
    $payload = $this->jwt->make((array) $sub)->toArray();
    $jwt = $this->jwt->encode($payload);

    $this->tokenMapper->add($payload, $refreshToken);
}

# SunAsterisk\Auth\Services\AuthJWTService;
public function refresh(?string $refreshToken, callable $callback = null): array
{
    ...
    return [
        'refresh_token' => 'eyJhbGciOiJIUzI1NiIsIn...',
        'access_token' => 'eyJiwibmFtZSI6Ikpva...',
        'token_type' => 'bearer',
        'expires_at' => 1675742447,
    ];
}

/**
* [socialSignIn]
* @param  string $provider                   [The Provider should received from https://socialiteproviders.com/about/]
* @return [Illuminate\Http\RedirectResponse]
*/
public function socialSignIn(?string $provider): RedirectResponse;

/**
* [socialCallback]
* @param  string $provider     [The Provider should received from https://socialiteproviders.com/about/]
* @return [stdClass]
*/
public function socialCallback(?string $provider): stdClass;

# SunAsterisk\Auth\Services\AuthSocialService
/**
 * [socialSignIn]
 * @param  string $provider [The Provider should received from https://socialiteproviders.com/about/]
 * @return [Illuminate\Http\RedirectResponse]
 */
public function socialSignIn(?string $provider): RedirectResponse
{
    try {
        return Socialite::driver($provider)->redirect();
    } catch (\Exception $e) {
        throw new InvalidArgumentException('provider is invalid!');
   

# SunAsterisk\Auth\Services\AuthSocialService
/**
 * [socialCallback]
 * @param  string $provider [The Provider should received from https://socialiteproviders.com/about/]
 * @return [stdClass]
 */
public function socialCallback(?string $provider): stdClass
{
    try {
        return Socialite::driver($provider)->user();
    } catch (\Exception $e) {
        throw new InvalidArgumentException('provider is invalid!');
    }
}
bash
composer 
bash

# config/app.php
return [
    // ...
    'providers' => [
        // ...
        SunAsterisk\Auth\SunServiceProvider::class
    ]
];
bash
php artisan vendor:publish --provider="SunAsterisk\Auth\SunServiceProvider" --tag=sun-asterisk
bash

// bootstrap/app.php

$app->register(SunAsterisk\Auth\SunServiceProvider::class);
bash
mkdir -p config
cp vendor/sun-asterisk/config/sun-asterisk.php config/sun-asterisk.php
bash
mkdir -p config
cp vendor/sun-asterisk/config/sun-asterisk.php config/sun-asterisk.php
bash
config/sun-asterisk.php
bash


return [
    'auth' => [
        /*
        |---------------------------------------------------------
        | Attribute login
        |---------------------------------------------------------
        |
        | E.g. 'email or username'
        |
        */
        'login_username' => 'email',
        /*
        |---------------------------------------------------------
        | Attribute field_credentials
        |---------------------------------------------------------
        | Use 1 of the list for authentication
        | E.g. 'username or email or phone'
        |
        */
        'field_credentials' => [
            'email',
        ],
        /*
        |---------------------------------------------------------
        | Attribute token_payload_fields
        |---------------------------------------------------------
        | Use the items in the list to create an access token
        |
        | E.g. 'id or email'
        |
        */
        'token_payload_fields' => [
            'id',
            'email',
        ],
        /*
        |---------------------------------------------------------
        | Attribute login
        |---------------------------------------------------------
        |
        | E.g. 'password or passwd'
        |
        */
        'login_password' => 'password',
        /*
        |---------------------------------------------------------
        | Model login
        |---------------------------------------------------------
        |
        | E.g. 'App\Models\User::class or App\Models\Admin::class'
        |
        */
        'model' => App\Models\User::class,
        /*
        |---------------------------------------------------------
        | Token forgot password
        |---------------------------------------------------------
        |
        | Default 5 minutes
        | E.g. '5'
        |
        */
        'token_expires' => 5, // minutes
        /*
        |---------------------------------------------------------
        | Key for jwt access token
        |---------------------------------------------------------
        |
        | E.g. 'xxxx'
        |
        */
        'jwt_key' => 'jwt_key',
        /*
        |---------------------------------------------------------
        | Key for jwt refresh access token
        |---------------------------------------------------------
        |
        | E.g. 'xxxx'
        |
        */
        'jwt_refresh_key' => 'jwt_refresh_key',
        /*
        |---------------------------------------------------------
        | TTL for jwt
        |---------------------------------------------------------
        |
        | Default 60 minutes
        | E.g. '60'
        |
        */
        'jwt_ttl' => 60, // minutes
        /*
        |---------------------------------------------------------
        | TTL for refresh access token
        |---------------------------------------------------------
        |
        | Default 20160 minutes
        | E.g. '60'
        |
        */
        'jwt_refresh_ttl' => 20160, // minutes
        /*
        |---------------------------------------------------------
        | use Socialite Providers for social login
        |---------------------------------------------------------
        |
        | Default false
        |
        */
        'enabled_social' => false,
    ],
];

bash
Route::group([
    'middleware' => 'auth:api',
], function ($router) {
    // routes
}
bash


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use SunAsterisk\Auth\Contracts\AuthJWTInterface;

class AuthController extends Controller
{
    protected AuthJWTInterface $service;

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


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use SunAsterisk\Auth\Contracts\AuthSessionInterface;

class AuthController extends Controller
{
    protected AuthSessionInterface $service;

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

POST /login
bash
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']);
}
bash
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');
}

POST /logout
bash
public function logout(Request $request)
{
   auth('api')->logout();

   return response()->noContent();
}
bash
public function logout(Request $request)
{
    $this->service->logout($request);

    return view('auth.login');
}

POST /register

POST /forgot-password

POST /refresh