diff --git a/ci4/app/Config/Auth.php b/ci4/app/Config/Auth.php index 57efc4ca..a1b84866 100644 --- a/ci4/app/Config/Auth.php +++ b/ci4/app/Config/Auth.php @@ -15,6 +15,7 @@ namespace Config; use App\Entities\Usuarios\UsersEntity; use App\Models\UserModel; +use CodeIgniter\Shield\Authentication\Authenticators\JWT; use CodeIgniter\Shield\Authentication\Passwords\ValidationRules; use CodeIgniter\Shield\Config\Auth as ShieldAuth; use CodeIgniter\Shield\Authentication\Actions\ActionInterface; @@ -118,7 +119,7 @@ class Auth extends ShieldAuth 'tokens' => AccessTokens::class, 'session' => Session::class, 'hmac' => HmacSha256::class, - // 'jwt' => JWT::class, + 'jwt' => JWT::class, ]; /** @@ -145,7 +146,7 @@ class Auth extends ShieldAuth 'session', 'tokens', 'hmac', - // 'jwt', + 'jwt', ]; /** diff --git a/ci4/app/Config/AuthJWT.php b/ci4/app/Config/AuthJWT.php new file mode 100644 index 00000000..a88cfcd8 --- /dev/null +++ b/ci4/app/Config/AuthJWT.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Config; + +use CodeIgniter\Shield\Config\AuthJWT as ShieldAuthJWT; + +/** + * JWT Authenticator Configuration + */ +class AuthJWT extends ShieldAuthJWT +{ + /** + * -------------------------------------------------------------------- + * Name of Authenticator Header + * -------------------------------------------------------------------- + * The name of Header that the Authorization token should be found. + * According to the specs, this should be `Authorization`, but rare + * circumstances might need a different header. + */ + public string $authenticatorHeader = 'Authorization'; + + /** + * -------------------------------------------------------------------- + * The Default Payload Items + * -------------------------------------------------------------------- + * All JWTs will have these claims in the payload. + * + * @var array + */ + public array $defaultClaims = [ + 'iss' => 'https://safekat.com', + ]; + + /** + * -------------------------------------------------------------------- + * The Keys + * -------------------------------------------------------------------- + * The key of the array is the key group name. + * The first key of the group is used for signing. + * + * @var array>> + * @phpstan-var array>> + */ + public array $keys = [ + 'default' => [ + // Symmetric Key + [ + 'kid' => '', // Key ID. Optional if you have only one key. + 'alg' => 'HS256', // algorithm. + // Set secret random string. Needs at least 256 bits for HS256 algorithm. + // E.g., $ php -r 'echo base64_encode(random_bytes(32));' + 'secret' => 'ZAfosrIVWDaKEhBhicTKCpW8T5ZxC3GYAxFgCkUQjlU=', + ], + // Asymmetric Key + // [ + // 'kid' => '', // Key ID. Optional if you have only one key. + // 'alg' => 'RS256', // algorithm. + // 'public' => '', // Public Key + // 'private' => '', // Private Key + // 'passphrase' => '' // Passphrase + // ], + ], + ]; + + /** + * -------------------------------------------------------------------- + * Time To Live (in seconds) + * -------------------------------------------------------------------- + * Specifies the amount of time, in seconds, that a token is valid. + */ + public int $timeToLive = HOUR; + + /** + * -------------------------------------------------------------------- + * Record Login Attempts + * -------------------------------------------------------------------- + * Whether login attempts are recorded in the database. + * + * Valid values are: + * - Auth::RECORD_LOGIN_ATTEMPT_NONE + * - Auth::RECORD_LOGIN_ATTEMPT_FAILURE + * - Auth::RECORD_LOGIN_ATTEMPT_ALL + */ + public int $recordLoginAttempt = Auth::RECORD_LOGIN_ATTEMPT_FAILURE; +} diff --git a/ci4/app/Config/Filters.php b/ci4/app/Config/Filters.php index 15d7414c..b626a639 100755 --- a/ci4/app/Config/Filters.php +++ b/ci4/app/Config/Filters.php @@ -8,6 +8,7 @@ use CodeIgniter\Filters\DebugToolbar; use CodeIgniter\Filters\Honeypot; use CodeIgniter\Filters\InvalidChars; use CodeIgniter\Filters\SecureHeaders; +use CodeIgniter\Shield\Authentication\Authenticators\JWT; class Filters extends BaseConfig @@ -43,6 +44,8 @@ class Filters extends BaseConfig 'login*', 'register', 'auth/a/*', + 'auth/jwt', + 'api/*', 'logout'] ], ], @@ -73,5 +76,9 @@ class Filters extends BaseConfig * Example: * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']] */ - public array $filters = []; + public array $filters = [ + /*'jwt' => [ + 'before' => ['api', 'api/*'] + ],*/ + ]; } diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index ff50b561..f71ccec6 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -755,16 +755,23 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route $routes->get('contact/(:num)/messages', 'ChatController::get_chat_internal_messages/$1', ['as' => 'getChatInternalMessages']); $routes->get('notifications', 'ChatController::get_chat_cliente/$1', ['as' => 'getChatCliente']); - - - - - - - - }); + +/* + * -------------------------------------------------------------------- + * APIs Route Definitions + * -------------------------------------------------------------------- + */ +$routes->post('auth/jwt', '\App\Controllers\Sistema\AuthAPIController::jwtLogin'); + +$routes->group('api', ['filter' => 'jwt'], static function ($routes) { + $routes->get('test', 'Test::echo'); + // ... +}); + + + /* * -------------------------------------------------------------------- * Additional Routing diff --git a/ci4/app/Controllers/Sistema/AuthAPIController.php b/ci4/app/Controllers/Sistema/AuthAPIController.php new file mode 100644 index 00000000..26487385 --- /dev/null +++ b/ci4/app/Controllers/Sistema/AuthAPIController.php @@ -0,0 +1,78 @@ +getValidationRules(); + + // Validate credentials + if (! $this->validateData($this->request->getJSON(true), $rules, [], config('Auth')->DBGroup)) { + return $this->fail( + ['errors' => $this->validator->getErrors()], + $this->codes['unauthorized'] + ); + } + + // Get the credentials for login + $credentials = $this->request->getJsonVar(setting('Auth.validFields')); + $credentials = array_filter($credentials); + $credentials['password'] = $this->request->getJsonVar('password'); + + /** @var Session $authenticator */ + $authenticator = auth('session')->getAuthenticator(); + + // Check the credentials + $result = $authenticator->check($credentials); + + // Credentials mismatch. + if (! $result->isOK()) { + // @TODO Record a failed login attempt + + return $this->failUnauthorized($result->reason()); + } + + // Credentials match. + // @TODO Record a successful login attempt + + $user = $result->extraInfo(); + + /** @var JWTManager $manager */ + $manager = service('jwtmanager'); + + // Generate JWT and return to client + $jwt = $manager->generateToken($user); + + return $this->respond([ + 'access_token' => $jwt, + ]); + } + + /** + * Returns the rules that should be used for validation. + * + * @return array|string>> + * @phpstan-return array>> + */ + protected function getValidationRules(): array + { + $rules = new ValidationRules(); + + return $rules->getLoginRules(); + } +} \ No newline at end of file diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index e78799d0..b3f99477 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -18,6 +18,12 @@ class Test extends BaseController { } + public function echo(){ + + echo "echo"; + + } + public function index() { /* diff --git a/ci4/composer.json b/ci4/composer.json index 70688ebd..f7dc1099 100755 --- a/ci4/composer.json +++ b/ci4/composer.json @@ -14,6 +14,7 @@ "codeigniter4/framework": "^4.0", "codeigniter4/shield": "^1.0", "dompdf/dompdf": "^2.0", + "firebase/php-jwt": "^6.10", "nicolab/php-ftp-client": "^2.0", "phpseclib/phpseclib": "~3.0" }, diff --git a/ci4/composer.lock b/ci4/composer.lock index 210fa59c..596e9a1b 100644 --- a/ci4/composer.lock +++ b/ci4/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0cf49081609029ebf2165c9cebed577e", + "content-hash": "07ccee0168bf5671a274f48a2ba42e77", "packages": [ { "name": "codeigniter4/framework", @@ -271,6 +271,69 @@ }, "time": "2024-04-29T13:06:17+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v6.10.1", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "500501c2ce893c824c801da135d02661199f60c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", + "reference": "500501c2ce893c824c801da135d02661199f60c5", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" + }, + "time": "2024-05-18T18:05:11+00:00" + }, { "name": "laminas/laminas-escaper", "version": "2.13.0",