Skip to content

Instantly share code, notes, and snippets.

@adactio
Last active January 20, 2023 16:09
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save adactio/8168e6b78da7b16a4644 to your computer and use it in GitHub Desktop.
Save adactio/8168e6b78da7b16a4644 to your computer and use it in GitHub Desktop.
Minimal micropub endpoint.
<?php
# Licensed under a CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
# http://creativecommons.org/publicdomain/zero/1.0/
$mysite = 'https://adactio.com/'; // Change this to your website.
$token_endpoint = 'https://tokens.indieauth.com/token';
$_HEADERS = array();
foreach(getallheaders() as $name => $value) {
$_HEADERS[$name] = $value;
}
if (!isset($_HEADERS['Authorization'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized');
echo 'Missing "Authorization" header.';
exit;
}
if (!isset($_POST['h'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
echo 'Missing "h" value.';
exit;
}
$options = array(
CURLOPT_URL => $token_endpoint,
CURLOPT_HTTPGET => TRUE,
CURLOPT_USERAGENT => $mysite,
CURLOPT_TIMEOUT => 5,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => FALSE,
CURLOPT_HTTPHEADER => array(
'Content-type: application/x-www-form-urlencoded',
'Authorization: '.$_HEADERS['Authorization']
)
);
$curl = curl_init();
curl_setopt_array($curl, $options);
$source = curl_exec($curl);
curl_close($curl);
parse_str($source, $values);
if (!isset($values['me'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
echo 'Missing "me" value in authentication token.';
exit;
}
if (!isset($values['scope'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
echo 'Missing "scope" value in authentication token.';
exit;
}
if (substr($values['me'], -1) != '/') {
$values['me'].= '/';
}
if (substr($mysite, -1) != '/') {
$mysite.= '/';
}
if (strtolower($values['me']) != strtolower($mysite)) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
echo 'Mismatching "me" value in authentication token.';
exit;
}
if (!stristr($values['scope'], 'post')) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
echo 'Missing "post" value in "scope".';
exit;
}
if (!isset($_POST['content'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
echo 'Missing "content" value.';
exit;
}
/* Everything's cool. Do something with the $_POST variables
(such as $_POST['content'], $_POST['category'], $_POST['location'], etc.)
e.g. create a new entry, store it in a database, whatever. */
header($_SERVER['SERVER_PROTOCOL'] . ' 201 Created');
header('Location: '.$mysite);
?>
Copy link

ghost commented May 9, 2015

void header ( string $string [, bool $replace = true [, int $http_response_code ]] )

header('Location: ' . $mysite, true, 201);

@aaronpk
Copy link

aaronpk commented Jan 28, 2018

fyi most Micropub clients have started using the create scope instead of post, so you'll likely want to change that on line 66

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment