This question already has answers here:
Call to undefined function apache_request_headers()
(6 answers)
Closed 5 years ago.
I'm only posting this because none of the other posts have helped solve my problem. I'm using slim and advanced rest api app on chrome for testing. I've tried many suggestions on the web but nothing is working. I'm running php 5.5 on hostgator. I am getting the error when passing authorization header:
call to undefined function apache_request_headers()
<?php
require_once '../include/DbHandler.php';
require_once '../include/PassHash.php';
require '.././libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
// User id from db - Global Variable
$user_id = NULL;
function authenticate(\Slim\Route $route) {
// Getting request headers
$headers = apache_request_headers();
$response = array();
$app = \Slim\Slim::getInstance();
// Verifying Authorization Header
if (isset($headers['Authorization'])) {
$db = new DbHandler();
// get the api key
$api_key = $headers['Authorization'];
// validating api key
if (!$db->isValidApiKey($api_key)) {
// api key is not present in users table
$response["error"] = true;
$response["message"] = "Access Denied. Invalid Api key";
echoRespnse(401, $response);
$app->stop();
} else {
global $user_id;
// get user primary key id
$user_id = $db->getUserId($api_key);
}
} else {
// api key is missing in header
$response["error"] = true;
$response["message"] = "Api key is misssing";
echoRespnse(400, $response);
//echoRespnse(400, $headers);
$app->stop();
}
}
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
Updating, this seems to take care of the the header problem
if (!function_exists('apache_request_headers')) {
function apache_request_headers() {
foreach($_SERVER as $key=>$value) {
if (substr($key,0,5)=="HTTP_") {
$key=str_replace(" ","-",ucwords(strtolower(str_replace("_"," ",substr($key,5)))));
$out[$key]=$value;
}else{
$out[$key]=$value;
}
}
return $out;
}
}
PHP 5.4.0 and later supports apache_request_headers(). But there are other solutions like the code below which comes from: http://php.net/manual/en/function.apache-request-headers.php
function apache_request_headers() {
$arh = array();
$rx_http = '/\AHTTP_/';
foreach($_SERVER as $key => $val) {
if( preg_match($rx_http, $key) ) {
$arh_key = preg_replace($rx_http, '', $key);
$rx_matches = array();
// do some nasty string manipulations to restore the original letter case
// this should work in most cases
$rx_matches = explode('_', $arh_key);
if( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {
foreach($rx_matches as $ak_key => $ak_val) $rx_matches[$ak_key] = ucfirst($ak_val);
$arh_key = implode('-', $rx_matches);
}
$arh[$arh_key] = $val;
}
}
return( $arh );
}
Related
I have been following this tutorial Tutorial and i managed to create the rest api with slim.
here is my .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
just as in the example and then when i go to my index.php
http://localhost/thefaith/v1/user/register
i get a an error
404 Page Not Found
The page you are looking for could not be found. Check the address bar to ensure your URL is spelled correctly. If all else fails, you can visit our home page at the link below.
but all my files are well arranged
plus below is my index.php which is in the v1 folder
<?php
include_once '../Includes/account_db_handler.php';
require '.././libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
// User register
$app->post('/user/register', function() use ($app) {
// check for required params
//verifyRequiredParams(array('name', 'email'));
$response = array();
// reading post params
//$name = $app->request->post('name');
//$email = $app->request->post('email');
// validating email address
//validateEmail($email);
//$db = new AcoountDbHandler();
//$response = $db->createUser($name, $email);
$response["message"] = "You are successfully registered";
// echo json response
echoRespnse(201, $response);
});
/**
* Verifying required params posted or not
*/
function verifyRequiredParams($required_fields) {
$error = false;
$error_fields = "";
$request_params = array();
$request_params = $_REQUEST;
// Handling PUT request params
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$app = \Slim\Slim::getInstance();
parse_str($app->request()->getBody(), $request_params);
}
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
// Required field(s) are missing or empty
// echo error json and stop the app
$response = array();
$app = \Slim\Slim::getInstance();
$response["error"] = true;
$response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
echoRespnse(400, $response);
$app->stop();
}
}
function echoRespnse($status_code, $response) {
$app = \Slim\Slim::getInstance();
// Http response code
$app->status($status_code);
// setting response content type to json
$app->contentType('application/json');
echo json_encode($response);
}
/**
* Validating email address
*/
function validateEmail($email) {
$app = \Slim\Slim::getInstance();
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$response["error"] = true;
$response["message"] = 'Email address is not valid';
echoRespnse(400, $response);
$app->stop();
}
}
$app->run();
?>
am still new using slim, need some help on how to solve this
I'm trying to use Ebay PHP SDK to connect to Ebay and fetch sellers selling item. For this I used following steps:
Step 1: Get authorize token and code for logged-in user. I used following code to implement.
use \DTS\eBaySDK\OAuth\Services as OauthService;
use \DTS\eBaySDK\OAuth\Types as OauthType;
use \DTS\eBaySDK\Constants;
use \DTS\eBaySDK\Trading\Services;
use \DTS\eBaySDK\Trading\Types;
use \DTS\eBaySDK\Trading\Enums;
$service = new OauthService\OAuthService([
'credentials' => $config['sandbox']['credentials'],
'ruName' => $config['sandbox']['ruName'],
'sandbox' => true
]);
$oauthParam = [
'client_id' => $config['sandbox']['credentials']['appId'],
'redirect_uri' => $config['sandbox']['redirect_uri'],
'response_type' => 'code',
'scope' => 'https://api.ebay.com/oauth/api_scope'
];
$urlParam = '';
$query = [];
foreach($oauthParam as $key => $param) {
$query[] = "$key=$param";
}
$urlParam = '?' . implode('&', $query);
$url = 'https://signin.sandbox.ebay.com/authorize' . $urlParam;
#session_start();
if(isset($_SESSION['ebay_oauth_token'])) {
$token = $_SESSION['ebay_oauth_token']['code'];
}
else {
if(isset($_GET['code'])) {
$token = $_GET['code'];
$_SESSION['ebay_oauth_token']['code'] = $token;
$request = new OauthType\GetUserTokenRestRequest();
$request->code = $token;
$response = $service->getUserToken($request);
if ($response->getStatusCode() !== 200) {
//Error
} else {
$_SESSION['ebay_oauth_token']['access_token'] = $response->access_token;
}
} else {
#header('location: ' . $url);
}
}
$userOauthToken = $_SESSION['ebay_oauth_token']['access_token'];
The above code is working as expected. That is the user is redirected to Sign In Page to authorize himself and get the set of Code and Access Token.
Step 2: Fetch Selling Items using code obtained from Step #1. I've used following code to implement the functionality.
$request->RequesterCredentials = new Types\CustomSecurityHeaderType();
$request->RequesterCredentials->eBayAuthToken = $token; //Obtained from Step 1
$request->ActiveList = new Types\ItemListCustomizationType();
$request->ActiveList->Include = true;
$request->ActiveList->Pagination = new Types\PaginationType();
$request->ActiveList->Pagination->EntriesPerPage = 10;
$request->ActiveList->Sort = Enums\ItemSortTypeCodeType::C_CURRENT_PRICE_DESCENDING;
$pageNum = 1;
do {
$request->ActiveList->Pagination->PageNumber = $pageNum;
$response = $service->getMyeBaySelling($request);
if (isset($response->Errors)) {
//Error Output
}
if ($response->Ack !== 'Failure' && isset($response->ActiveList)) {
foreach ($response->ActiveList->ItemArray->Item as $item) {
//Output response
}
}
$pageNum += 1;
} while ({condition});
I'm having problem in Step #2. It is generating Invalid Token while running the code.
I would highly appreciate if anyone help me.
You are mixing the requests. In the second part of your code, the request belongs to the Trading API that uses the Auth'n'Auth token, and you are trying to make the call using the OAuth token. These 2 tokens are different and work for different APIs.
You have 2 options.
Either keep the second part of your code, which appears to be correct, actually, but use the Auth'n'Auth token (that you can generate from the developer account). In this case, the first part is useless.
Keep the first part of your code, and delete the second part. In this case, you need to rewrite your second part of code using the OAuth API instead of the Trading API.
Following is the code I am using.
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app = new \Slim\App;
function handle_response($output, $response){
if($output['status'] === "failed"){
$response = $response->withStatus(400);
$response->getBody()->write(json_encode($output));
}
else{
$response->getBody()->write(json_encode($output));
}
return $response;
}
/* user profile */
$app->get('/user/profile', function (Request $request, Response $response) {
$headers = $request->getHeaders();
foreach ($headers as $name => $values) {
$name . ": " . implode(", ", $values);
}
if ($request->hasHeader('Authorization')) {
$output['token'] = 'yes';
}
else
$output['token'] = $name;
$output['status'] = "success";
return handle_response($output, $response);
});
I am using postman in google chrome to test this REST service.
I am passing a custom header "Authorization" along with the GET request.
however, this program doesn't recognize any custom headers.
The code block
$headers = $request->getHeaders();
foreach ($headers as $name => $values) {
$name . ": " . implode(", ", $values);
}
only returns the header "HTTP_ACCEPT_LANGUAGE".
Please help me to figure out, what went wrong here.
It is not Slim, it is considered a PHP feature. If you are sending something else than valid HTTP Basic Authorization header, PHP will not have access to it. You can work around this by adding the following rewrite rule to your .htaccess file.
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Another way is to use apache_request_headers() but it is Apache specific and not portable.
I have been using Slim v2 for my APIs and am thinking about upgrading to v3.
Unfortunately I have limited experience and could use your help on a code example below.
This is the login code:
$app->post('/register', function() use ($app) {
// check for required params
verifyRequiredParams(array('name', 'email', 'password'));
$response = array();
// reading post params
$name = $app->request->post('name');
$email = $app->request->post('email');
$password = $app->request->post('password');
// validating email address
validateEmail($email);
$db = new DbHandler();
$res = $db->createUser($name, $email, $password);
if ($res == USER_CREATED_SUCCESSFULLY) {
$response["error"] = false;
$response["message"] = "You are successfully registered";
} else if ($res == USER_CREATE_FAILED) {
$response["error"] = true;
$response["message"] = "Oops! An error occurred while registereing";
} else if ($res == USER_ALREADY_EXISTED) {
$response["error"] = true;
$response["message"] = "Sorry, this email already existed";
}
// echo json response
echoRespnse(201, $response);
});
Here is the validateEmail function:
function validateEmail($email) {
$app = \Slim\Slim::getInstance();
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$response["error"] = true;
$response["message"] = 'Email address is not valid';
echoRespnse(400, $response);
$app->stop();
}
}
How do I get an Instance of app in Slim v3 to actually stop the app when input criteria are not met?
I would appreciate it if you could give me an example with the help of my code.
Thanks for the help!
EDIT
The above issue was solved. Unfortunately, a new issue arose after checking my code.
I have a middle layer to authenticate the user:
function authenticate(\Slim\Route $route) {
// Getting request headers
$headers = apache_request_headers();
$response = array();
$app = \Slim\Slim::getInstance();
// Verifying Authorization Header
if (isset($headers['Authorization'])) {
//omitted code
} else {
// api key is missing in header
$response["error"] = true;
$response["message"] = "Api key is misssing";
echoRespnse(400, $response);
$app->stop();
}
In my main code i implement function authenticate as follows:
$app->get('/tasks', 'authenticate', function() {
global $user_id;
$response = array();
$db = new DbHandler();
//ommit some code
echoRespnse(200, $response);
});
Would you know how to do this in Slim v3?
I would really appreciate your help.
In Slim3, return $response (return Response object) is a better way to stop app.
So how is the below?
$app->post('/register', function($request, $response, $args) {
// omit some codes
if(!validateEmail($request->getParsedBodyParam('email'))){
return $response->withJson(['message' => 'Email address is not valid', 'error' => true], 400);
}
// omit some codes
}
validateEmail function is changed to like below.
function validateEmail($email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return false
}
return true;
}
Hope it will help you.
https://coinbase.com/api/v1/transactions/send_money?api_key=xxx
I have that URL but after the api_key paramter what comes next (I blocked out my API Key so people can't access my BTC)?
Can someone give me an example of how to properly use coinbase's send_money API?
I don't have a PHP environment handy to test this with but I think it would go like this:
Get their PHP library: https://github.com/coinbase/coinbase-php
<?php
require_once(dirname(__FILE__) . '/../lib/Coinbase.php');
// Create an application at https://coinbase.com/oauth/applications and set these values accordingly
$_CLIENT_ID = "83a481f96bf28ea4bed1ee8bdc49ba4265609efa40d40477c2a57e913c479065";
$_CLIENT_SECRET = "a8dda20b94d09e84e8fefa5e7560133d9c5af9da93ec1d3e79ad0843d2920bbb";
// Note: your redirect URL should use HTTPS.
$_REDIRECT_URL = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$coinbaseOauth = new Coinbase_OAuth($_CLIENT_ID, $_CLIENT_SECRET, $_REDIRECT_URL);
if(isset($_GET['code'])) {
// Request tokens
$tokens = $coinbaseOauth->getTokens($_GET['code']);
// The user is now authenticated! Access and refresh tokens are in $tokens
// Store these tokens safely, and use them to make Coinbase API requests in the future.
// For example:
$coinbase = new Coinbase($coinbaseOauth, $tokens);
try {
echo 'Balance: ' . $coinbase->sendMoney($to, $amount, $notes=null, $userFee=null, $amountCurrency=null) . '<br>';
echo $coinbase->createButton("Alpaca socks", "10.00", "CAD")->embedHtml;
} catch (Coinbase_TokensExpiredException $e) {
$newTokens = $coinbaseOauth->refreshTokens($tokens);
// Store $newTokens and retry request
}
} else {
// Redirect to Coinbase authorization page
// The provided parameters specify the access your application will have to the
// user's account; for a full list, see https://coinbase.com/docs/api/overview
// You can pass as many scopes as you would like
echo "Connect with Coinbase";
}
Here is the send money code
public function sendMoney($to, $amount, $notes=null, $userFee=null, $amountCurrency=null)
{
$params = array( "transaction[to]" => $to );
if($amountCurrency !== null) {
$params["transaction[amount_string]"] = $amount;
$params["transaction[amount_currency_iso]"] = $amountCurrency;
} else {
$params["transaction[amount]"] = $amount;
}
if($notes !== null) {
$params["transaction[notes]"] = $notes;
}
if($userFee !== null) {
$params["transaction[user_fee]"] = $userFee;
}
return $this->post("transactions/send_money", $params);
}