Skip to content

Instantly share code, notes, and snippets.

@leekelleher
Forked from adactio/micropub.php
Last active August 2, 2026 12:35
Show Gist options
  • Select an option

  • Save leekelleher/9e4276064314a420df5a6fd11e92024f to your computer and use it in GitHub Desktop.

Select an option

Save leekelleher/9e4276064314a420df5a6fd11e92024f to your computer and use it in GitHub Desktop.
Minimal micropub endpoint.
<?php
# Minimal micropub endpoint by @adactio.
# https://gist.github.com/adactio/8168e6b78da7b16a4644
# Licensed under a CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
# http://creativecommons.org/publicdomain/zero/1.0/
# Modifications by @leekelleher.
$site_url = 'https://leekelleher.com/';
$token_endpoint = 'https://tokens.indieauth.com/token';
$_HEADERS = array();
foreach(getallheaders() as $name => $value) {
$_HEADERS[$name] = $value;
}
if (!isset($_HEADERS['Authorization']) && !isset($_POST['access_token'])) {
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;
}
$access_token = isset($_HEADERS['Authorization']) ? $_HEADERS['Authorization'] : 'Bearer ' . $_POST['access_token'];
$options = array(
CURLOPT_URL => $token_endpoint,
CURLOPT_HTTPGET => TRUE,
CURLOPT_USERAGENT => $site_url,
CURLOPT_TIMEOUT => 5,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => FALSE,
CURLOPT_HTTPHEADER => array(
'Content-type: application/x-www-form-urlencoded',
'Authorization: '.$access_token
)
);
$curl = curl_init();
curl_setopt_array($curl, $options);
$source = curl_exec($curl);
curl_close($curl);
parse_str($source, $values);
$dump1 = print_r($values, TRUE);
$file = fopen('_values.txt', 'w');
fwrite($file, $dump1);
fclose($file);
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($site_url, -1) != '/') {
$site_url .= '/';
}
if (strtolower($values['me']) != strtolower($site_url)) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
echo 'Mismatching "me" value in authentication token.';
exit;
}
if (!stristr($values['scope'], 'create')) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
echo 'Missing "create" 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. */
$dump = print_r($_POST, TRUE);
$file = fopen('_data.txt', 'a');
fwrite($file, $dump);
fclose($file);
header($_SERVER['SERVER_PROTOCOL'] . ' 201 Created');
header("Location: $site_url");
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment