Skip to content

Instantly share code, notes, and snippets.

@manuhabitela
Created October 9, 2013 16:54
Show Gist options
  • Save manuhabitela/6904467 to your computer and use it in GitHub Desktop.
Save manuhabitela/6904467 to your computer and use it in GitHub Desktop.
CakePHP + Steam OpenID : beginning of some code that will probably never be finished.
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Auth' => array(
'authenticate' => array(
'FormValue' => array(
'field' => 'steam_id',
'userModel' => 'User'
)
),
'authorize' => 'Controller'
),
'Session'
);
public function beforeFilter() {
$this->Auth->allow('validate_steam');
}
public function isAuthorized($user = null) {
return true;
}
}
<?php
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
class FormValueAuthenticate extends BaseAuthenticate {
public function authenticate(CakeRequest $request, CakeResponse $response) {
$model = $this->settings['userModel'];
$field = $this->settings['field'];
return ClassRegistry::init($model)->find('first', array(
'conditions' => array(
$field => $request->data[$model][$field]
)
));
}
}
<?php
/**
*
* @package Steam Community API
* @copyright (c) 2010 ichimonai.com
* @license http://opensource.org/licenses/mit-license.php The MIT License
*
*/
class SteamSignIn
{
const STEAM_LOGIN = 'https://steamcommunity.com/openid/login';
/**
* Get the URL to sign into steam
*
* @param mixed returnTo URI to tell steam where to return, MUST BE THE FULL URI WITH THE PROTOCOL
* @param bool useAmp Use &amp; in the URL, true; or just &, false.
* @return string The string to go in the URL
*/
public static function genUrl($returnTo = false, $useAmp = true)
{
$returnTo = (!$returnTo) ? (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] : $returnTo;
$params = array(
'openid.ns' => 'http://specs.openid.net/auth/2.0',
'openid.mode' => 'checkid_setup',
'openid.return_to' => $returnTo,
'openid.realm' => (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'],
'openid.identity' => 'http://specs.openid.net/auth/2.0/identifier_select',
'openid.claimed_id' => 'http://specs.openid.net/auth/2.0/identifier_select',
);
$sep = ($useAmp) ? '&amp;' : '&';
return self::STEAM_LOGIN . '?' . http_build_query($params, '', $sep);
}
/**
* Validate the incoming data
*
* @return string Returns the SteamID64 if successful or empty string on failure
*/
public static function validate()
{
// Star off with some basic params
$params = array(
'openid.assoc_handle' => $_GET['openid_assoc_handle'],
'openid.signed' => $_GET['openid_signed'],
'openid.sig' => $_GET['openid_sig'],
'openid.ns' => 'http://specs.openid.net/auth/2.0',
);
// Get all the params that were sent back and resend them for validation
$signed = explode(',', $_GET['openid_signed']);
foreach($signed as $item)
{
$val = $_GET['openid_' . str_replace('.', '_', $item)];
$params['openid.' . $item] = get_magic_quotes_gpc() ? stripslashes($val) : $val;
}
// Finally, add the all important mode.
$params['openid.mode'] = 'check_authentication';
// Stored to send a Content-Length header
$data = http_build_query($params);
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' =>
"Accept-language: en\r\n".
"Content-type: application/x-www-form-urlencoded\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
'content' => $data,
),
));
$result = file_get_contents(self::STEAM_LOGIN, false, $context);
// Validate wheather it's true and if we have a good ID
preg_match("#^http://steamcommunity.com/openid/id/([0-9]{17,25})#", $_GET['openid_claimed_id'], $matches);
$steamID64 = is_numeric($matches[1]) ? $matches[1] : 0;
// Return our final value
return preg_match("#is_valid\s*:\s*true#i", $result) == 1 ? $steamID64 : '';
}
}
<?php
App::uses('AppModel', 'Model');
class User extends AppModel {
public function updateFromSteam($steamId, $createOnly = false) {
if (empty($steamId) || !is_numeric($steamId))
return false;
$existingUser = $this->findBySteamId($steamId);
if ($existingUser && $createOnly)
return false;
$user = array('steam_id' => $steamId);
$urlFormat = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?format=xml&key=%s&steamids=%s";
$url = sprintf($urlFormat, Configure::read('Steam.Key'), $steamId);
libxml_use_internal_errors(true);
$xml = @simplexml_load_file($url);
if ($xml) {
$user['username'] = (string) $xml->players->player->personaname;
$user['avatar'] = (string) $xml->players->player->avatar;
}
if (!$existingUser)
$this->create($user);
else {
$this->id = $existingUser[$this->alias]['id'];
$this->set($user);
}
$this->save();
}
public function createFromSteam($steamId) {
return $this->updateFromSteam($steamId, true);
}
}
<?php
App::import('Vendor', 'SteamSignIn');
class UsersController extends AppController {
public function login() {
$this->set('loginUrl', SteamSignIn::genUrl(Router::url(array('controller' => 'users', 'action' => 'validate_steam'), true)));
}
public function validate_steam() {
$steamId = SteamSignIn::validate();
if (is_numeric($steamId)) {
$this->request->data['User']['steam_id'] = $steamId;
$this->User->createFromSteam($steamId);
}
if ($this->Auth->login()) {
//cool. cool cool cool
} else {
$this->Session->setFlash(__('There was an error during authentication with Steam'), 'default', array(), 'auth');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment