Pular para o conteúdo principal

Login Integration with JWT

Authentication, password management, and JWT issuance are powered by byjg/authuser. This section describes how the default wiring works and what you need to change when you customize users or credentials.

Database Schema

Two tables ship with the reference architecture:

CREATE TABLE `users` (
`userid` BINARY(16) DEFAULT (uuid_to_bin(uuid())) NOT NULL,
`name` VARCHAR(50),
`email` VARCHAR(120),
`username` VARCHAR(20) NOT NULL,
`password` CHAR(40) NOT NULL,
`role` VARCHAR(50),
`created_at` DATETIME DEFAULT (NOW()),
`updated_at` DATETIME ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` DATETIME,
PRIMARY KEY (`userid`),
UNIQUE KEY `ix_username` (`username`),
UNIQUE KEY `ix_email` (`email`)
) ENGINE=InnoDB;

CREATE TABLE `users_property` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50),
`value` VARCHAR(250),
`userid` BINARY(16) NOT NULL,
CONSTRAINT `fk_user_property` FOREIGN KEY (`userid`) REFERENCES `users` (`userid`)
) ENGINE=InnoDB;
  • users.role drives the built-in RBAC helpers (User::ROLE_ADMIN / User::ROLE_USER). Add more roles if needed.
  • users_property stores arbitrary metadata (profile picture, MFA flags, etc.) and is automatically loaded by UsersService.

Model Mapping

Models live in src/Model and already extend the AuthUser abstractions:

  • RestReferenceArchitecture\Model\User extends ByJG\Authenticate\Model\UserModel. It uses FieldUuidAttribute and OpenAPI attributes to sync the schema.
  • RestReferenceArchitecture\Model\UserProperties extends ByJG\Authenticate\Model\UserPropertiesModel.

To customize fields, either modify these models or create your own classes and update the container bindings described below.

AuthUser Service Configuration

config/dev/02-security.php wires the repositories and service:

use ByJG\Authenticate\Enum\LoginField;
use ByJG\Authenticate\Repository\UserPropertiesRepository;
use ByJG\Authenticate\Repository\UsersRepository;
use ByJG\Authenticate\Service\UsersService;
use RestReferenceArchitecture\Model\User;
use RestReferenceArchitecture\Model\UserProperties;

return [
UsersRepository::class => DI::bind(UsersRepository::class)
->withInjectedConstructorOverrides([
'usersClass' => User::class,
])
->toSingleton(),

UserPropertiesRepository::class => DI::bind(UserPropertiesRepository::class)
->withInjectedConstructorOverrides([
'propertiesClass' => UserProperties::class,
])
->toSingleton(),

UsersService::class => DI::bind(UsersService::class)
->withInjectedConstructorOverrides([
'loginField' => LoginField::Email, // or LoginField::Username
])
->toSingleton(),
];
  • Swap LoginField::Email for LoginField::Username if you prefer username-based logins.
  • If you add custom user models, update the usersClass / propertiesClass overrides.

Password Policy Configuration

The password policy also lives in config/dev/02-security.php:

use ByJG\Authenticate\Definition\PasswordDefinition;

return [
PasswordDefinition::class => DI::bind(PasswordDefinition::class)
->withConstructorArgs([[
PasswordDefinition::MINIMUM_CHARS => 12,
PasswordDefinition::REQUIRE_UPPERCASE => 1,
PasswordDefinition::REQUIRE_LOWERCASE => 1,
PasswordDefinition::REQUIRE_SYMBOLS => 1,
PasswordDefinition::REQUIRE_NUMBERS => 1,
PasswordDefinition::ALLOW_WHITESPACE => 0,
PasswordDefinition::ALLOW_SEQUENTIAL => 0,
PasswordDefinition::ALLOW_REPEATED => 0,
]])
->toSingleton(),
];

AuthUser uses the mapper configured on User::$password to hash passwords (PasswordSha1Mapper by default). Override the mapper if you need a different algorithm.

JWT Configuration

Secret & Wrapper

JwtWrapper bindings read the secret from each environment’s credentials.env file.

# config/dev/credentials.env
JWT_SECRET=jwt_super_secret_key
use ByJG\Config\Param;
use ByJG\JwtWrapper\JwtHashHmacSecret;
use ByJG\JwtWrapper\JwtKeyInterface;
use ByJG\JwtWrapper\JwtWrapper;

return [
JwtKeyInterface::class => DI::bind(JwtHashHmacSecret::class)
->withConstructorArgs([Param::get('JWT_SECRET')])
->toSingleton(),

JwtWrapper::class => DI::bind(JwtWrapper::class)
->withConstructorArgs([Param::get('API_SERVER'), Param::get(JwtKeyInterface::class)])
->toSingleton(),
];

Never commit secrets—each environment gets its own config/<env>/credentials.env.

Available Endpoints

src/Rest/Login.php provides:

EndpointDescription
POST /loginValidate credentials, return JWT
POST /refreshtokenRefresh an expiring token (last 5 minutes)
POST /login/resetrequestSend password reset token + email code
POST /login/confirmcodeConfirm the email + code pair
POST /login/resetpasswordSet a new password after confirmation
GET /sampleprotected/pingSample endpoint requiring authentication

The password reset flow sends emails through ByJG\Mail\Wrapper\MailWrapperInterface. Customize the sender/template in config/dev/06-external.php, which defines the MAIL_ENVELOPE factory.

Testing Authentication

# Obtain a token
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"username":"[email protected]","password":"!P4ssw0rdstr!"}'

# Use the token
curl -X GET http://localhost:8080/sampleprotected/ping \
-H "Authorization: Bearer YOUR_TOKEN_HERE"

Using JWT in Your Code

Protect Endpoints

use RestReferenceArchitecture\Attributes\RequireAuthenticated;
use RestReferenceArchitecture\Attributes\RequireRole;
use RestReferenceArchitecture\Model\User;

class MyProtectedRest
{
#[RequireAuthenticated]
public function getProtectedData(HttpResponse $response): void
{
$response->write(['message' => 'You are authenticated!']);
}

#[RequireRole(User::ROLE_ADMIN)]
public function getAdminData(HttpResponse $response): void
{
$response->write(['message' => 'You are an admin!']);
}
}

Read JWT Claims

use RestReferenceArchitecture\Util\JwtContext;

// JwtContext::parseJwt() runs inside the middleware pipeline
$userId = JwtContext::getUserId();
$userName = JwtContext::getName();
$userRole = JwtContext::getRole(); // e.g., "admin" or "user"

Need the full payload? Access HttpRequest::param('jwt.data') directly, but prefer JwtContext helpers to keep controllers focused.

Additional Resources

  • src/Rest/Login.php – Reference implementation for all endpoints.
  • src/Util/JwtContext.php – Helper used by controllers and tests.
  • config/dev/02-security.php – Central location for auth wiring.