I have written a voting class in Laravel. It uses the voting sites API to check if the user has voted today. A user is only allowed to vote once every day.
All votes reset at midnight (i.e. 12:00 AM Chicago time) and I create a cookie to not bother wasting a curl response till then, so the cookie expires when a new vote is allowed.
The API returns response codes: 2 means the user hasn't voted for them in the past 24 hours, and 3 means they have voted for them in the past 24 hours. Just think of 2 as 0 and 3 as 1 in a false/true situation.
The reason I am asking this question is I don't think I am handling cookies the best way I can. Could anyone advise a better way to create them? I wasn't sure how to do it without a response, as Laravel says you have to send it with a response.
If the user needs to vote, they are sent to the voting page. For now I've just put a temp link as http://need2vote.com until I finish the class.
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Auth;
use Redirect;
use Illuminate\Support\Facades\Route;
use Cookie;
use Illuminate\Http\Request;
use Config;
class VotingController extends Controller
{
protected $pageUsername;
protected $requestTimeout;
protected $usingCloudflare;
protected $apiUrl;
public function __construct()
{
$this->pageUsername = Config::get('voting.username');
$this->requestTimeout = Config::get('voting.timeout');
$this->usingCloudflare = true;
$this->apiUrl = Config::get('voting.api_url');
}
public function checkVote(Request $request)
{
if (Config::get('voting.enabled') == false) {
return;
}
if ($this->isVoteCookieSet()) {
return;
}
$urlRequest = $this->apiUrl . 'user=' . $this->pageUsername . '&ip=' . $request->ip();
$result = $this->makeCurlRequest($urlRequest, $this->requestTimeout);
if ($result == 3) {
$this->redirectToVote();
}
else {
$this->setVoteCookie();
}
}
private function makeCurlRequest($url, $timeout)
{
if (function_exists('curl_version'))
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
$requestData = curl_exec($curl);
curl_close($curl);
}
else
{
$requestData = stream_context_create(array('http' => array('timeout' => $timeout)));
return file_get_contents($url, 0, $requestData);
}
return $requestData;
}
public function redirectToVote() {
header('Location: http://needtovote.com');
exit();
}
private function setVoteCookie() {
$rankingsResetTime = $this->getVoteResetTime();
setcookie('vote_timestamp', $rankingsResetTime, $rankingsResetTime);
}
private function isVoteCookieSet() {
if (isset($_COOKIE['voting_timestamp'])) {
if ($_COOKIE['voting_timestamp'] == $this->getVoteResetTime()) {
return true;
}
else{
setcookie('voting_timestamp', '');
return false;
}
}
return false;
}
private function getVoteResetTime() {
$serverDefaultTime = date_default_timezone_get();
date_default_timezone_set('America/Chicago');
$rankingsResetTime = mktime(0, 0, 0, date('n'), date('j') + 1);
date_default_timezone_set($serverDefaultTime);
return $rankingsResetTime;
}
}
voting.username
and so on. If those values come from the browser client (via query parameters or cookie values), then it's super easy for anyone to vote as many times as they want. Also, do you want users to be able to vote multiple times by clearing their cookies in between, or not? This will affect how you use cookies in your design. \$\endgroup\$