Skip to Content
API v1Authentication

Authentication

JWT Implementation

The API uses JSON Web Tokens (HS256) for authentication. The JWT library is vendored at api/libs/php-jwt-master/ (Firebase PHP-JWT).

Token Structure

{ "iat": 1700000000, "iss": "https://api.myhousr.com/api/", "data": { "id": "123" } }
  • iat - Issued at (Unix timestamp)
  • iss - Issuer (always https://api.myhousr.com/api/)
  • data.id - The user’s database ID

Note: Tokens have no expiry (exp) claim. They remain valid indefinitely unless the signing key changes.

Signing Key

The signing key is defined in api/include/core.php:

$key = "example_key";

This is a global variable available to all endpoint files via the bootstrap chain.

Token Generation

Tokens are created during login, signup, and social auth flows:

$token = array( "iat" => $issued_at, "iss" => $issuer, "data" => array( "id" => $userId, ) ); $jwt = JWT::encode($token, $key);

Token Validation

Endpoints validate tokens in two ways:

1. Direct Decode (most endpoints)

The endpoint manually decodes the JWT from $_POST["jwt"]:

$jwt = isset($_POST["jwt"]) ? $_POST["jwt"] : ""; $decoded = JWT::decode($jwt, $key, array('HS256')); $userId = $decoded->data->id;

If the token is invalid, JWT::decode() throws an exception. Endpoints typically catch this and return 401.

2. Utility Functions (newer endpoints)

api/utils/jwtUtils.php provides helper functions:

// Required auth - returns user ID or dies with 401 $userId = getUserId($jwt); // Optional auth - returns user ID or null $userId = getOptionalUserId($jwt);

Token Delivery

The JWT is passed to the API in two ways:

  1. POST body field (legacy pattern, most endpoints):

    POST /api/houses.php Content-Type: application/x-www-form-urlencoded jwt=eyJ...
  2. Authorization header (newer endpoints like viewings.php, getBillsData.php):

    GET /api/viewings.php Authorization: eyJ...

    Note: No Bearer prefix is used. The raw JWT is sent directly in the Authorization header.

Auth Patterns by Endpoint Type

PatternExampleDescription
Required POSTchatRooms.phpJWT in POST body, 401 if missing/invalid
Required Headerviewings.phpJWT in Authorization header, 401 if missing
OptionalgetHouse.phpWorks without JWT; shows extra data (likes, friends) when authenticated
PublicfeatureFlags.php, cities.phpNo auth required
API KeyExternal endpointsUses apiKeyChecker.php to validate API keys from api_keys table

SSO Authentication (US)

US university users authenticate via SAML SSO using SimpleSAMLphp:

  1. api/sso_login.php - Initiates SAML auth flow, redirects to university IdP
  2. After IdP callback, a temporary JWT is created containing SAML attributes
  3. api/sso_auth.php - Receives the temporary JWT, extracts collegeUID, looks up or creates the user, returns a standard app JWT

The SAML configuration lives in the saml/ directory and SimpleSAMLphp is installed at /var/www/simplesamlphp in the container.

Social Authentication

  • Apple Sign-In (appleSignin.php) - Receives Apple userID, looks up user by appleID column
  • Google Sign-In (googleSignin.php) - Receives Google credentials, verifies via Google API client
  • Facebook Sign-In (facebookSignin.php) - Receives Facebook credentials

All social auth endpoints follow the same pattern: look up existing user by provider ID, create if not found, return JWT.

OTP (One-Time Password)

Used for password reset and phone verification:

  1. send_otp.php - Generates a 6-digit OTP, stores it in the users table (otp, otp_create_at, otp_is_expired columns), sends via Twilio SMS
  2. verify_otp.php - Validates the OTP
  3. signUpOtp.php - OTP during signup flow
Last updated on