Authentication
The $yorauth->auth() resource covers the full user authentication lifecycle: registration, login, logout, token refresh, password reset, email verification, passwordless magic links, and TOTP multi-factor authentication.
The PHP SDK is currently in development. This documentation describes the intended API. The package is not yet published to Packagist.
Register
Register a new user for your application.
API endpoint: POST /api/v1/applications/{applicationId}/users/register
$user = $yorauth->auth()->register([
'email' => 'jane@example.com',
'password' => 'super-secret-password',
'name' => 'Jane Doe',
'metadata' => [ // optional
'plan' => 'starter',
'referral_code' => 'ABC123',
],
]);
echo $user['id']; // uuid
echo $user['email']; // 'jane@example.com'
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User email address |
password | string | Yes | Minimum 8 characters |
name | string | Yes | Display name |
metadata | array | No | Custom key/value pairs stored on the user record |
Returns: array — The created user. HTTP 201.
After registration, a verification email is sent. The user must verify their email before they can log in, unless email verification is disabled in your application settings.
Login
Authenticate a user with email and password.
API endpoint: POST /api/v1/applications/{applicationId}/users/login
$result = $yorauth->auth()->login('jane@example.com', 'super-secret-password');
// Or with options:
$result = $yorauth->auth()->login('jane@example.com', 'super-secret-password', [
'remember_me' => true, // optional — extends refresh token lifetime
]);
if ($result['mfa_required'] ?? false) {
// Store challenge_token and redirect to MFA step
$challengeToken = $result['challenge_token'];
$mfaMethods = $result['mfa_methods']; // ['totp']
} else {
$accessToken = $result['data']['access_token'];
$refreshToken = $result['data']['refresh_token'];
$expiresIn = $result['data']['expires_in']; // seconds
$user = $result['data']['user'];
}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
$email | string | Yes | User email address |
$password | string | Yes | User password |
$options | array | No | Additional options (e.g. remember_me, captcha_token) |
Returns: array — Either access_token, refresh_token, expires_in, user — or mfa_required: true with challenge_token and mfa_methods.
Logout
Revoke the current refresh token and invalidate the access token.
API endpoint: POST /api/v1/applications/{applicationId}/users/logout
$yorauth->auth()->logout($refreshToken);
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
$refreshToken | string | Yes | The user's current refresh token |
Refresh Token
Exchange a refresh token for a new access token and refresh token pair.
API endpoint: POST /api/v1/applications/{applicationId}/users/token/refresh
$tokens = $yorauth->auth()->refreshToken($refreshToken);
$newAccessToken = $tokens['access_token'];
$newRefreshToken = $tokens['refresh_token']; // rotation — store the new one
$expiresIn = $tokens['expires_in'];
Password Reset
Request Reset Link
Send a password reset email to the user.
API endpoint: POST /api/v1/applications/{applicationId}/users/password/forgot
$yorauth->auth()->forgotPassword('jane@example.com');
// Always succeeds — never reveals whether the email exists.
Reset Password
Complete the password reset using the token from the email link.
API endpoint: POST /api/v1/applications/{applicationId}/users/password/reset
$yorauth->auth()->resetPassword([
'token' => 'token-from-email-link',
'email' => 'jane@example.com',
'password' => 'new-super-secret-password',
]);
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Token from the password reset email |
email | string | Yes | User email address |
password | string | Yes | New password (minimum 8 characters) |
Email Verification
Verify Email
API endpoint: POST /api/v1/applications/{applicationId}/users/email/verify
$yorauth->auth()->verifyEmail('token-from-verification-email');
Resend Verification Email
API endpoint: POST /api/v1/applications/{applicationId}/users/email/resend
$yorauth->auth()->resendVerification('jane@example.com');
Magic Links (Passwordless)
Request a Magic Link
API endpoint: POST /api/v1/applications/{applicationId}/users/magic-link
$yorauth->auth()->requestMagicLink('jane@example.com');
// Or with a redirect URL:
$yorauth->auth()->requestMagicLink('jane@example.com', 'https://myapp.com/auth/callback');
// Always succeeds — never reveals whether the email exists.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
$email | string | Yes | User email address |
$redirectUrl | string | No | URL to redirect to after verification. Must be an allowed redirect URL configured in your app settings |
Verify a Magic Link
After the user clicks the link, exchange the token for a session.
API endpoint: POST /api/v1/applications/{applicationId}/users/magic-link/verify
$session = $yorauth->auth()->verifyMagicLink($tokenFromQueryString);
$accessToken = $session['access_token'];
$refreshToken = $session['refresh_token'];
$user = $session['user'];
$redirectUrl = $session['redirect_url']; // set during request, if any
Multi-Factor Authentication (TOTP)
MFA Setup
1. Begin TOTP Setup
API endpoint: POST /api/v1/applications/{applicationId}/users/{userId}/mfa/totp/setup
$setup = $yorauth->mfa()->setupTotp($userId, 'My App'); // label is optional — shown in authenticator apps
$methodId = $setup['data']['method_id']; // needed for confirm step
$provisioningUri = $setup['data']['provisioning_uri']; // otpauth:// URI
Render the provisioning_uri as a QR code using a library such as endroid/qr-code so the user can scan it with their authenticator app.
2. Confirm TOTP Setup
API endpoint: POST /api/v1/applications/{applicationId}/users/{userId}/mfa/totp/confirm
$result = $yorauth->mfa()->confirmTotp($userId, $setup['data']['method_id'], '123456');
$backupCodes = $result['data']['backup_codes']; // string[] — display once and store securely
Display backup codes to the user immediately after setup. They cannot be retrieved again. The user should store them securely.
Disable TOTP
API endpoint: DELETE /api/v1/applications/{applicationId}/users/{userId}/mfa/totp
$yorauth->mfa()->disableTotp($userId, $currentPassword); // password required for re-authentication
Get MFA Status
API endpoint: GET /api/v1/applications/{applicationId}/users/{userId}/mfa/status
$status = $yorauth->mfa()->getStatus($userId);
$status['data']['mfa_enabled']; // bool
$status['data']['methods']; // array of active MFA methods
$status['data']['backup_codes_remaining']; // int
Regenerate Backup Codes
API endpoint: POST /api/v1/applications/{applicationId}/users/{userId}/mfa/backup-codes/regenerate
$result = $yorauth->mfa()->regenerateBackupCodes($userId, $currentPassword);
$result['data']['backup_codes']; // new codes — previous ones are now invalid
MFA Challenge (Login)
When login() returns mfa_required: true, complete authentication with:
API endpoint: POST /api/v1/applications/{applicationId}/users/mfa/verify
$loginResult = $yorauth->auth()->login('jane@example.com', 'secret');
if ($loginResult['mfa_required'] ?? false) {
// Accept the code from the user (e.g. from a request input)
$session = $yorauth->auth()->verifyMfa([
'challenge_token' => $loginResult['challenge_token'],
'code' => $request->input('code'), // 6-digit TOTP or 8-char backup code
]);
$accessToken = $session['data']['access_token'];
$user = $session['data']['user'];
}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
challenge_token | string | Yes | The challenge_token from the login response |
code | string | Yes | 6-digit TOTP code or 8-character backup code |
Laravel Examples
Auth Controller
namespace App\Http\Controllers\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use YorAuth\Laravel\Facades\YorAuth;
use YorAuth\Sdk\Exceptions\YorAuthException;
class LoginController extends Controller
{
public function login(Request $request): JsonResponse
{
$request->validate([
'email' => 'required|email',
'password' => 'required|string',
]);
try {
$result = YorAuth::auth()->login(
$request->email,
$request->password,
['remember_me' => $request->boolean('remember_me')],
);
} catch (YorAuthException $e) {
return response()->json([
'message' => $e->getMessage(),
'code' => $e->errorCode,
], $e->statusCode);
}
if ($result['mfa_required'] ?? false) {
return response()->json([
'mfa_required' => true,
'challenge_token' => $result['challenge_token'],
]);
}
return response()->json([
'access_token' => $result['data']['access_token'],
'refresh_token' => $result['data']['refresh_token'],
'expires_in' => $result['data']['expires_in'],
]);
}
}
Protected Route with Middleware
// routes/api.php
Route::middleware('yorauth.authenticated')->group(function () {
Route::get('/me', function (Request $request) {
return response()->json($request->user());
});
});
Next Steps
- Authorization — Check permissions, manage roles