Skip to content

Commit b98a024

Browse files
Merge pull request #10 from Crowdhandler/sanitizeURL
Added a method to strip crowdhandler parameters and redirect on promo…
2 parents 546f812 + 4ec3d08 commit b98a024

7 files changed

Lines changed: 83 additions & 24 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ composer.phar
66
composr.lock
77
favicon.ico
88
php.ini
9-
.idea/
9+
.idea/
10+
.DS_Store

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ Set the cookie
7272

7373
#### Automatic
7474

75-
$gatekeeper->setCookie();
7675

77-
Now you set the cookie so that the user carries their token with each request.
78-
This is important, if the token cannot be checked, a new one will be issued, and this may result in a promoted user being sent to a waiting room.
76+
We automatically set the cookie so that the user carries their token with each request.
7977

8078
#### Go your own way
8179

composer.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/flat-php/advanced.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<?php
22

33
/*
4-
In this example, we will use the session object instead of cookies.
5-
And we will handle the redirect ourselves instead of relying on CrowdHandlee\GateKeeper
4+
In this example, we will handle the redirect ourselves instead of relying on CrowdHandler\GateKeeper
65
We will also specify a slug to redirect to if the request check fails.
76
*/
87

@@ -11,9 +10,7 @@
1110
$api = new CrowdHandler\PublicClient('ace1f8062f2df869a5fb0cbd69f51c10d2821dd1e4519e110206eca9e3db86c8'); // your public key here.
1211
$ch = new CrowdHandler\GateKeeper($api);
1312
$ch->setSafetyNetSlug('sandbox'); // users will be directed to a known slug (must be one of yours) if API request or response fails
14-
$ch->setToken( (isset($_URL['ch-id']) ? $_URL['ch-id'] : isset($_SESSION['ch-id'])) ? $_SESSION['ch-id'] : null );
1513
$ch->checkRequest();
16-
$_SESSION['ch-id'] = $ch->result->token; // we do not recommend using default session for token storage, this is just an example.
1714
if(!$ch->result->promoted) {
1815
header('location:'.$ch->getRedirectUrl(), 302);
1916
}

examples/flat-php/basic.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
$api = new CrowdHandler\PublicClient('ace1f8062f2df869a5fb0cbd69f51c10d2821dd1e4519e110206eca9e3db86c8'); // your public key here.
66
$ch = new CrowdHandler\GateKeeper($api);
77
$ch->checkRequest();
8-
$ch->setCookie();
98
$ch->redirectIfNotPromoted();
109

1110
?>

examples/slim-framework-psr/web/index.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@
1010
// We pass Slim's PSR7 request instead of having GateKeeper corale info from CGI variables
1111
$ch = new CrowdHandler\GateKeeper($api, $request);
1212
$ch->checkRequest();
13-
// We use Slim to set the cookie, not the method inside GateKeeper
14-
$cookies = new Slim\Http\Cookies();
15-
$cookies->set('ch-id', ['value' => $ch->result->token, 'path'=>'/']);
13+
1614
if($ch->result->promoted) {
1715
// Here you would build your response as normal. We're just rendering the CrowdHandler Result
1816
$response->getBody()->write($ch->result);
1917
// Now log the performance, we're about to dispatch the response
2018
$ch->recordPerformance(200);
21-
return $response->withHeader('Set-Cookie', $cookies->toHeaders());
19+
return $response;
2220
} else {
23-
return $response->withHeader('Set-Cookie', $cookies->toHeaders())->withRedirect($ch->getRedirectUrl(), 302);
21+
return $response->withRedirect($ch->getRedirectUrl(), 302);
2422
}
2523
});
2624
$app->run();

src/GateKeeper.php

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ class GateKeeper
99
const TOKEN_COOKIE = 'ch-id';
1010
const TOKEN_URL = 'ch-id';
1111

12+
const CROWDHANDLER_PARAMS = array(
13+
'ch-id',
14+
'ch-fresh',
15+
'ch-id-signature',
16+
'ch-public-key',
17+
'ch-requested',
18+
'ch-code'
19+
);
20+
1221
private $ignore = "/^((?!.*\?).*(\.(avi|css|eot|gif|ico|jpg|jpeg|js|json|mov|mp4|mpeg|mpg|og[g|v]|pdf|png|svg|ttf|txt|wmv|woff|woff2|xml))$)/";
1322
private $client;
1423
private $failTrust = true;
@@ -40,20 +49,53 @@ public function __construct(Client $client, \Psr\Http\Message\ServerRequestInter
4049
$server = $_SERVER;
4150
$cookies = $_COOKIE;
4251
}
52+
53+
54+
// Token in URL
4355
if (isset($get[self::TOKEN_URL])) {
44-
$this->token = $get[self::TOKEN_URL];
56+
$this->setCookie($get[self::TOKEN_URL]);
57+
// clean url and redirect
58+
$this->sanitizeURL($this->url, $get);
59+
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
60+
header('location: '.$this->url, true, self::HTTP_REDIRECT_CODE);
61+
exit;
62+
4563
} elseif (isset($cookies[self::TOKEN_COOKIE])) {
4664
$this->token = $cookies[self::TOKEN_COOKIE];
4765
}
48-
// now we've extracted the token we sanitize the url
49-
$this->url = 'https://' . parse_url($this->url, PHP_URL_HOST) . parse_url($this->url, PHP_URL_PATH);
50-
unset($get[self::TOKEN_URL]);
51-
if(count($get)) $this->url .= '?' . http_build_query($get);
66+
5267
$this->detectClientIp($server);
5368
if (isset($server['HTTP_USER_AGENT'])) $this->agent = $server['HTTP_USER_AGENT'];
5469
if (isset($server['HTTP_ACCEPT_LANGUAGE'])) $this->lang = $server['HTTP_ACCEPT_LANGUAGE'];
5570
}
5671

72+
/**
73+
* Removes crowdhandler specific query parameters on promotion
74+
* @param string $url The url that is currently being requested
75+
* @param array $get An array of the current query sring parameters
76+
*/
77+
private function sanitizeURL ($url, $get)
78+
{
79+
80+
$parsed_url = parse_url($url);
81+
$this->url = 'https://' . $parsed_url['host'] . $parsed_url['path'];
82+
83+
$ch_params_to_remove = array();
84+
for ($i=0; $i < Count(self::CROWDHANDLER_PARAMS); $i++) {
85+
if (isset($get[self::CROWDHANDLER_PARAMS[$i]]))
86+
{
87+
array_push($ch_params_to_remove, $get[self::CROWDHANDLER_PARAMS[$i]]);
88+
}
89+
}
90+
91+
$remaining_query_parameters = array_diff($get, $ch_params_to_remove);
92+
93+
if (Count($remaining_query_parameters) > 0) {
94+
$this->url = $this->url .= '?' . http_build_query($remaining_query_parameters);
95+
}
96+
97+
}
98+
5799
private function detectClientIp($server)
58100
{
59101
if (array_key_exists('HTTP_X_FORWARDED_FOR', $server)) {
@@ -155,7 +197,10 @@ public function checkRequest()
155197
$this->result = $this->client->requests->get($this->token, $params);
156198
} else {
157199
$this->result = $this->client->requests->post($params);
158-
}
200+
}
201+
if(isset($this->result->token)) {
202+
$this->setCookie($this->result->token);
203+
}
159204
}
160205
catch (\Exception $e) {
161206
$mock = new ApiObject;
@@ -201,11 +246,11 @@ public function getRedirectUrl()
201246
/**
202247
* Set CrowdHandler session cookie
203248
*/
204-
public function setCookie()
249+
private function setCookie($cookie)
205250
{
206-
if (!is_null($this->result->token)) {
207-
setcookie(self::TOKEN_COOKIE, $this->result->token, 0, '/', '', $this->debug ? false: true);
208-
$this->debug('Setting cookie '.$this->result->token);
251+
if (!is_null($cookie)) {
252+
setcookie(self::TOKEN_COOKIE, $cookie, 0, '/', '', $this->debug ? false: true);
253+
$this->debug('Setting cookie '.$cookie);
209254
}
210255
}
211256

0 commit comments

Comments
 (0)