class wfJWT {
private $claims;
const JWT_TTL = 600;
const ISSUER = 600;
public static function extractTokenContents($token) {
if (!is_string($token)) {
throw new InvalidArgumentException('Token is not a string. ' . gettype($token) . ' given.');
}
// Verify the token matches the JWT format.
if (!preg_match('/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?$/', $token)) {
throw new wfJWTException('Invalid token format.');
}
list($header, $body, $signature) = explode('.', $token);
// Test that the token is valid and not expired.
$decodedHeader = base64_decode($header);
if (!(is_string($decodedHeader) && $decodedHeader)) {
throw new wfJWTException('Token header is invalid.');
}
$header = json_decode($decodedHeader, true);
if (!is_array($header)) {
throw new wfJWTException('Token header is invalid.');
}
$decodedBody = base64_decode($body);
if (!(is_string($decodedBody) && $decodedBody)) {
throw new wfJWTException('Token body is invalid.');
}
$body = json_decode($decodedBody, true);
if (!is_array($body)) {
throw new wfJWTException('Token body is invalid.');
}
return array(
'header' => $header,
'body' => $body,
'signature' => $signature,
);
}
/**
* @param mixed $subject
*/
public function __construct($subject = null) {
$this->claims = $this->getClaimDefaults();
$this->claims['sub'] = $subject;
}
/**
* @return string
*/
public function encode() {
$header = $this->encodeString($this->buildHeader());
$body = $this->encodeString($this->buildBody());
return sprintf('%s.%s.%s', $header, $body,
$this->encodeString($this->sign(sprintf('%s.%s', $header, $body))));
}
/**
* @param string $token
* @return array
* @throws wfJWTException|InvalidArgumentException
*/
public function decode($token) {
if (!is_string($token)) {
throw new InvalidArgumentException('Token is not a string. ' . gettype($token) . ' given.');
}
// Verify the token matches the JWT format.
if (!preg_match('/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?$/', $token)) {
throw new wfJWTException('Invalid token format.');
}
list($header, $body, $signature) = explode('.', $token);
// Verify signature matches the supplied payload.
if (!$this->verifySignature($this->decodeString($signature), sprintf('%s.%s', $header, $body))) {
throw new wfJWTException('Invalid signature.');
}
// Test that the token is valid and not expired.
$decodedHeader = base64_decode($header);
if (!(is_string($decodedHeader) && $decodedHeader)) {
throw new wfJWTException('Token header is invalid.');
}
$header = json_decode($decodedHeader, true);
if (!(
is_array($header) &&
array_key_exists('alg', $header) &&
$header['alg'] === 'HS256' &&
$header['typ'] === 'JWT'
)) {
throw new wfJWTException('Token header is invalid.');
}
$decodedBody = base64_decode($body);
if (!(is_string($decodedBody) && $decodedBody)) {
throw new wfJWTException('Token body is invalid.');
}
$body = json_decode($decodedBody, true);
if (!(
is_array($body) &&
// Check the token not before now timestamp.
array_key_exists('nbf', $body) &&
is_numeric($body['nbf']) &&
$body['nbf'] <= time() &&
// Check the token is not expired.
array_key_exists('exp', $body) &&
is_numeric($body['exp']) &&
$body['exp'] >= time() &&
// Check the issuer and audience is ours.
$body['iss'] === 'Wordfence ' . WORDFENCE_VERSION &&
$body['aud'] === 'Wordfence Central'
)) {
throw new wfJWTException('Token is invalid or expired.');
}
return array(
'header' => $header,
'body' => $body,
);
}
/**
* @param string $string
* @return string
*/
public function sign($string) {
$salt = wp_salt('auth');
return hash_hmac('sha256', $string, $salt, true);
}
/**
* @param string $signature
* @param string $message
* @return bool
*/
public function verifySignature($signature, $message) {
return hash_equals($this->sign($message), $signature);
}
/**
* @return string
*/
public function __toString() {
return $this->encode();
}
/**
* @param string $data
* @return string
*/
public function encodeString($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
/**
* @param string $data
* @return bool|string
*/
public function decodeString($data) {
return base64_decode(strtr($data, '-_', '+/'));
}
/**
* @return mixed|string
*/
protected function buildHeader() {
return '{"alg":"HS256","typ":"JWT"}';
}
/**
* @return mixed|string
*/
protected function buildBody() {
return json_encode($this->getClaims());
}
/**
* @return array
*/
protected function getClaimDefaults() {
$now = time();
return array(
'iss' => 'Wordfence ' . WORDFENCE_VERSION,
'aud' => 'Wordfence Central',
'nbf' => $now,
'iat' => $now,
'exp' => $now + self::JWT_TTL,
);
}
/**
* @param array $claims
*/
public function addClaims($claims) {
if (!is_array($claims)) {
throw new InvalidArgumentException(__METHOD__ . ' expects argument 1 to be array.');
}
$this->setClaims(array_merge($this->getClaims(), $claims));
}
/**
* @return array
*/
public function getClaims() {
return $this->claims;
}
/**
* @param array $claims
*/
public function setClaims($claims) {
$this->claims = $claims;
}
}
class wfJWTException extends Exception {
}
Who Founded YouTube?
YouTube was founded by three former PayPal employees: Chad Hurley, Steve Chen, and Jawed Karim. They combined product thinking, engineering skills, and a clear user goal: create a website where anyone could upload a video and watch it instantly in a browser.
Chad Hurley — product/design focus and early CEO role
Steve Chen — engineering and infrastructure
Jawed Karim — engineering and early concept support
The Problem YouTube Solved
At the time, sharing video often meant emailing huge files or dealing with complicated players and downloads. YouTube made video:
Uploadable by non-experts (simple interface)
Streamable in the browser (no special setup)
Sharable through links and embedding on other sites
Early Growth and the First Video
YouTube launched publicly in 2005. One of the most famous early moments was the first uploaded video, “Me at the zoo,” featuring co-founder Jawed Karim. The clip was short and casual—exactly the kind of everyday content that proved the platform’s big idea: ordinary people could publish video without needing a studio.
Key Milestones Timeline
Year/Date Milestone Why It Mattered
2005 YouTube is founded and launches Introduced easy browser-based video sharing
2005 “Me at the zoo” is uploaded Became a symbol of user-generated video culture
2006 Google acquires YouTube Provided resources to scale hosting and global reach
Why Google Bought YouTube
By 2006, YouTube’s traffic was exploding. Video hosting is expensive—bandwidth and storage costs rise fast when millions of people watch content daily. Google’s acquisition gave YouTube the infrastructure and advertising ecosystem to grow into a sustainable business.
What YouTube’s Founding Changed
YouTube didn’t just create a popular website; it reshaped how people learn, entertain themselves, and build careers online. Its founding helped accelerate:
Creator-driven media and influencer culture
How-to education and free tutorials at massive scale
Music discovery, commentary, and global community trends
From a small startup idea to a global video powerhouse, YouTube’s founding is a classic example of a simple product solving a real problem—and changing the internet in the process.