Skip to main content

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

php
$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:

ParameterTypeRequiredDescription
emailstringYesUser email address
passwordstringYesMinimum 8 characters
namestringYesDisplay name
metadataarrayNoCustom 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

php
$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:

ParameterTypeRequiredDescription
$emailstringYesUser email address
$passwordstringYesUser password
$optionsarrayNoAdditional 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

php
$yorauth->auth()->logout($refreshToken);

Parameters:

ParameterTypeRequiredDescription
$refreshTokenstringYesThe 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

php
$tokens = $yorauth->auth()->refreshToken($refreshToken);

$newAccessToken  = $tokens['access_token'];
$newRefreshToken = $tokens['refresh_token']; // rotation — store the new one
$expiresIn       = $tokens['expires_in'];

Password Reset

Send a password reset email to the user.

API endpoint: POST /api/v1/applications/{applicationId}/users/password/forgot

php
$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

php
$yorauth->auth()->resetPassword([
    'token'    => 'token-from-email-link',
    'email'    => 'jane@example.com',
    'password' => 'new-super-secret-password',
]);

Parameters:

ParameterTypeRequiredDescription
tokenstringYesToken from the password reset email
emailstringYesUser email address
passwordstringYesNew password (minimum 8 characters)

Email Verification

Verify Email

API endpoint: POST /api/v1/applications/{applicationId}/users/email/verify

php
$yorauth->auth()->verifyEmail('token-from-verification-email');

Resend Verification Email

API endpoint: POST /api/v1/applications/{applicationId}/users/email/resend

php
$yorauth->auth()->resendVerification('jane@example.com');

API endpoint: POST /api/v1/applications/{applicationId}/users/magic-link

php
$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:

ParameterTypeRequiredDescription
$emailstringYesUser email address
$redirectUrlstringNoURL to redirect to after verification. Must be an allowed redirect URL configured in your app settings

After the user clicks the link, exchange the token for a session.

API endpoint: POST /api/v1/applications/{applicationId}/users/magic-link/verify

php
$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

php
$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

php
$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

php
$yorauth->mfa()->disableTotp($userId, $currentPassword); // password required for re-authentication

Get MFA Status

API endpoint: GET /api/v1/applications/{applicationId}/users/{userId}/mfa/status

php
$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

php
$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

php
$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:

ParameterTypeRequiredDescription
challenge_tokenstringYesThe challenge_token from the login response
codestringYes6-digit TOTP code or 8-character backup code

Laravel Examples

Auth Controller

php
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

php
// routes/api.php
Route::middleware('yorauth.authenticated')->group(function () {
    Route::get('/me', function (Request $request) {
        return response()->json($request->user());
    });
});

Next Steps