#}
Authentication Guide
Master JWT setup, user login, and protecting routes with role-based access control
Authentication Guide
Overview
GEMVC provides a robust JWT (JSON Web Token) authentication system with built-in support for role-based access control (RBAC). The system uses HS256 signatures and supports multiple token types for different use cases.
Access Token 5 min (short-lived)
Refresh Token 1 hour (medium-lived)
Login Token 7 days (long-lived)
HS256 Signature Secure signing
info: 90% of GEMVC security is AUTOMATIC! JWT verification happens when you call $request->auth() - no manual token parsing needed.
Environment Configuration
Configure JWT settings in your .env file:
.env
# JWT Security
TOKEN_SECRET='your-very-long-random-secret-key-here'
TOKEN_ISSUER='MyCompany'
# Token Expiration (in seconds)
ACCESS_TOKEN_VALIDATION_IN_SECONDS=300 # 5 minutes
REFRESH_TOKEN_VALIDATION_IN_SECONDS=3600 # 1 hour
LOGIN_TOKEN_VALIDATION_IN_SECONDS=604800 # 7 days
Tip: Use a long, random string for TOKEN_SECRET. Never commit it to version control!
Token Types
Creating Tokens (JWTToken Class)
JWTToken.php
use Gemvc\Http\JWTToken;
// Access Token - Short-lived for API calls (5 min default)
$accessToken = (new JWTToken())->createAccessToken($userId);
// Refresh Token - Medium-lived for token renewal (1 hour default)
$refreshToken = (new JWTToken())->createRefreshToken($userId);
// Login Token - Long-lived for remember me (7 days default)
$loginToken = (new JWTToken())->createLoginToken($userId);
// With additional data
$token = (new JWTToken())->createAccessToken($userId, [
'role' => 'admin,user',
'role_id' => 1,
'company_id' => 5
]);
Token Payload Structure
JWT Payload
{
"token_id": "unique-token-id",
"user_id": 123,
"role": "admin,user",
"role_id": 1,
"company_id": 5,
"employee_id": 10,
"branch_id": 2,
"exp": 1234567890,
"iss": "MyCompany",
"type": "access"
}
Authentication in API Services
Basic Authentication Check
User.php
// In your API service
public function update(): JsonResponse
{
// Verify JWT token - returns 401 if invalid
if (!$this->request->auth()) {
return $this->request->returnResponse();
}
// User is authenticated, continue...
return (new UserController($this->request))->update();
}
Role-Based Authorization
Admin.php
// Require specific roles - returns 403 if unauthorized
public function delete(): JsonResponse
{
// Only 'admin' or 'moderator' roles can access
if (!$this->request->auth(['admin', 'moderator'])) {
return $this->request->returnResponse();
}
// User has required role, continue...
return (new AdminController($this->request))->delete();
}
Tip: The auth() method checks BOTH authentication (valid token) and authorization (correct role). No separate checks needed!
Password Security
GEMVC uses Argon2i for password hashing - the industry standard for secure password storage:
CryptHelper.php
use Gemvc\Helper\CryptHelper;
// Hash password (Argon2i)
$hashedPassword = CryptHelper::hashPassword($plainPassword);
// Verify password
$isValid = CryptHelper::passwordVerify($plainPassword, $hashedPassword);
if ($isValid) {
// Password matches!
}
Complete Login Example
Complete Login Example
// app/api/Auth.php
class Auth extends ApiService
{
public function login(): JsonResponse
{
// Validate input
if (!$this->request->definePostSchema([
'email' => 'email',
'password' => 'string'
])) {
return $this->request->returnResponse();
}
return (new AuthController($this->request))->login();
}
}
// app/controller/AuthController.php
class AuthController extends Controller
{
public function login(): JsonResponse
{
$email = $this->request->post['email'];
$password = $this->request->post['password'];
// Find user
$user = (new UserModel())->selectByEmail($email);
if (!$user) {
return Response::unauthorized('Invalid credentials');
}
// Verify password
if (!CryptHelper::passwordVerify($password, $user->password)) {
return Response::unauthorized('Invalid credentials');
}
// Generate tokens
$jwt = new JWTToken();
$accessToken = $jwt->createAccessToken($user->id, [
'role' => $user->role
]);
$refreshToken = $jwt->createRefreshToken($user->id);
return Response::success([
'access_token' => $accessToken,
'refresh_token' => $refreshToken,
'user' => $user
], 1, 'Login successful');
}
}
Security Features
- HS256 Signature - Secure HMAC-SHA256 token signing
- Expiration Validation - Automatic token expiry checking
- User ID Validation - Ensures user_id > 0 in tokens
- Multi-Role Support - Comma-separated roles (admin,user)
- Token Renewal - Built-in renew() method for extending tokens
- Argon2i Passwords - Memory-hard hashing algorithm