Throwback Thursday: Laconica API Authentication when PHP is run as CGI

Author’s note: This is an old post from 2009. I decided to repost it here in case it might still be useful to someone who’s dealing with a similar problem. Sorry for some dead links. Also sorry if it doesn’t work anymore. Heck, it probably isn’t even necessary anymore.

Woah, 3 acronyms in a title. That’s enough to scare someone off. 😉

Really though, I’m running my Laconica Microblogging instance at Hap.Pi.Ly. I’ve gotten almost everything working now, except queues–damn pcntl_fork()! Or rather, damn my host for not enabling the pcntl PHP module!

But this post isn’t about queues. It’s about getting the API to work on a system who’s running PHP as a CGI rather than as an Apache module. The issue is that running PHP as CGI breaks HTTP Basic Authentication which the Twitter style API depends on. So it took me some time, but I figured out how to make it work.

In .htaccess add the following line right after the RewriteBase:

RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},QSA]

This tells the server to pass the authentication information as a POST argument. Even though you would think it would pass it as $_SERVER[‘REMOTE_USER’], on my server (and I suspect many others, it gets passed as $_SERVER[‘REDIRECT_REMOTE_USER’]

Then, you need to retrieve that variable in the PHP code. There may be another way of doing this, but I finally settled on changing the following code in actions/api.php

Find the lines:

if ($this->requires_auth()) {
if (!isset($_SERVER['PHP_AUTH_USER'])) {

Change to:

if ($this->requires_auth()) {

if (!($_SERVER['REDIRECT_REMOTE_USER'])) { 

Find the lines:

} else {
$nickname = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$user = common_check_user($nickname, $password);

Change to:

} else {
list($nickname, $password) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)));
$user = common_check_user($nickname, $password);

Note for the future: The variable $_SERVER[‘GATEWAY_INTERFACE’] reports that the server is using the CGI method. Therefore, I need to write an IF-THEN that checks this variable. Then this whole thing can be added into production code.