I am writing php code to authenticate a user using the Discouse SSO provider feature. I enabled the enable sso provider option and set a sso secret in the login settings. I found the help to use this option very sparse and spread out throughout the meta. A post by @ntauthority proved useful. So Here is my code so far:
<?php
class GenericSSO {
public function __construct($apiEndpoint) {
$this->apiEndpoint = $apiEndpoint;
$this->headers = array();
}
public function call($method, $action,$params) {
$url = $this->apiEndpoint.$action;
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if($method=="POST"){
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params) );
}
elseif ($method == "GET") {
curl_setopt($ch, CURLOPT_URL, $url.'?'.http_build_query($params));
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->headers );
//
}
else {
die("Method must be POST or GET");
}
$exec = curl_exec($ch);
$info = curl_getinfo($ch);
//print_r($exec);
if($info["http_code"] == 200) {
curl_close($ch);
return json_decode($exec,true);
} else {
die("An error happened:<pre>".curl_error($ch));
}
}
public function add_header($name, $value){
array_push($this->headers, "$name: $value");
}
}
$api = new GenericSSO("http://discouse.example.com");
$results = $api->call('GET', '/session/csrf.json', array());
$csrf = $results['csrf'];
# not working
/*
$params = array(
'login' => 'username',
'password' => 'thepassword'
);
$api->add_header("X-CSRF-Token", $csrf);
//*/
# working
/*
$api_key = 'theapikeyasdfjiJIDFJISDJFISDJFISJDFISJDFIJSDF';
$api_user = 'bob';
$params = array(
'login' => 'username',
'password' => 'thepassword',
'api_key' => $api_key,
'api_username' => $api_user
);
//*/
$api->add_header("Content-Type", "application/x-www-form-urlencoded");
$results = $api->call('POST', '/session.json', $params);
print "<pre>results:\n";
print_r($results);
This will get the csrf without issue. I then expected that it would just need to pass the login and password, with the csrf header. This is the "# not working" section of the code. But, if I include the api_key and api_user, it will login the user, with or without the csrf and will fail if the password is wrong (this is the "# working" part).
Here is the weird, part, the former seems to work if I use the postman chrome extension. First I get the csrf (note, I replaces real url and keys with example ones):
Then I make a post to session.conf
with the csrf header, it work:
and if the csrf is bad:
and if I include the api_key with no header, it works:
Any advice on how to write the code would great.