Check if my GET request has Header: Token - php

I want to send a request with or without 'Token' as a header.
If request has 'Token' as a header: if the user already has that item, it will return the item with the proper item_id of a specific user (based on its token), otherwise it will return null.
If request doesn't have 'Token' as a header: it will return the item with that item_id
I'm working with Zend Framework and in ItemResource I have this method:
public function fetch($id)
{
}
How can I check if my request has Token as a header or not and implement both cases inside fetch()?

Using Laminas API Tools it depends on wether you 're using a RPC or a REST resource. I will explain which tools the Laminas API Tools give you to evaluate the received header data.
You don 't have to reinvent the wheel, because Laminas API Tools has the received headers already at hand, when you 're in your fetch method.
Representational State Transfer (REST)
Rest resources normally extend the \Laminas\ApiTools\Rest\AbstractResourceListener class. This class listens for \Laminas\ApiTools\Rest\ResourceEvent. Fortunately, this event provides you with a request object that also contains the received header data.
<?php
declare(strict_types=1);
namespace Marcel\V1\Rest\Example;
use Laminas\ApiTools\Rest\AbstractResourceListener;
class ExampleResource extends AbstractResourceListener
{
public function fetch($id)
{
// requesting for an authorization header
$token = $this->getEvent()->getRequest()->getHeader('Authorization', null);
if ($token === null) {
// header was not received
}
}
}
As you can see the ResourceEvent returns a \Laminas\Http\Request instance when calling getRequest(). The request instance already contains all request headers you 've received. Just call getHeader with the given name and as second parameter a default value, which should be returned, when the header was not set. If there is no http_token header, you 'll get null as a result.
Remote Procedure Calls (RPC)
Since RPC requests are handled with a MVC controller class, you can get the request as easy as in a rest resource. Controller classes extend from \Laminas\Mvc\Controller\AbstractActionController, which already contains a request instance.
<?php
declare(strict_types=1);
namespace Marcel\V1\Rpc\Example;
use Laminas\Mvc\Controller\AbstractActionController;
class ExampleController extends AbstractActionController
{
public function exampleAction()
{
$token = $this->getRequest()->getHeader('Authorization', null);
if ($token === null) {
// token was not set
}
}
}
As you can see getting header data in rpc requests is as easy as in resource listeners. The procedure is the same because a request instance is also used here.
Conclusion
There is absolutely no need for coding things, that are already there. Just get the request instance from the event or the abstract controller and retrieve the header you want. Always keep in mind, that there are security aspects like CRLF injections, when dealing with raw data. The Laminas framework handles all this for you already.
Additionally you can check for all received headers by calling ->getHeaders() instead of ->getHeader($name, $default). You 'll get a \Laminas\Http\Header instance with all received headers.

You can get all HTTP header values by getallheaders() or just get the specific value by $_SERVER['HTTP_XXX'], in your case, replace XXX with Token, $_SERVER['HTTP_Token'].
Manual: https://www.php.net/manual/en/reserved.variables.server.php
public function fetch($id)
{
$token = $_SERVER['HTTP_Token'];
// do your busniess code
}

Related

How to add HEADER in apache_request_headers in PHP

I want to add a header, to request headers, dynamically on the server side.
I am using slim 2 framework which supports middleware.
Here is my usecase:
Client initiates request to url "https://somedomain.com/login" with some Request Headers.
I have middleware say authenticate. Which should add say "UserAddress" to Request Header.
My callback function login() is called. And I need to access "UserAddress" from header.
So following is the code for this route:
function login() {
//Login related stuff
$allHeaders = apache_request_headers();
//Perform some operation on UserAdress from $allHeaders
}
function authenticate(\Slim\Route $route) {
//Perform authentication here
//I am using SUPERFICIAL method `set_apache_request_headers` as reference.
//Here I need to know how I can add new header to REQUEST HEADER
set_apache_request_headers('UserAdress', 'New York');
//Here is what I tried, which did not work when I called apache_request_headers()
//$_SERVER["UserAdress"] = "New York";
}
$app = getSlimInstance();
$app->post('/login', 'authenticate', login);
I tried using $_SERVER, but when I call apache_request_headers(), my header does not show up.
Side Note:
I am using "UserAddress" as my header for reference purpose. Actually I am using different name.
Also I know you guys will say pass that via request body. But due to legacy code I need this in request header.
I just need to know how can I modify the Request Header

CakePHP response stop deprecated

I'm using CakePHP 3.5 and two of the methods I want to use are deprecated and I can't find an alternative.
The methods are:
$this->response->send();
$this->response->stop();
I want to redirect to a different page and stop the execution of the current method. I've tried calling die() after my redirect and it doesn't work.
According to the migration guide the methods have been made obsolete.
Any thoughts?
Edit:
I'm trying to redirect users without access to certain pages. This is in the initialize() method in the controllers.
if ($allowedAccess) {
$this->Flash->error("Insufficient rights to access that location");
$this->redirect($this->referer());
// FIXME - find alternative to deprecated methods
return $this->response;
$this->response->send();
$this->response->stop();
}
Are you trying this in a controller? Simply return the response object from your controllers method:
public function index() {
// Some code
return $this->response;
}
send() was just a wrapper around phps exit(). Use exit() if you need to somewhere.
What happens when you return the response is that the ActionDispatcher processes the return value and if it's a Response object. See the __invoke() method.
The response will go through the middleware layer and will be finally send by the ResponseEmitter which is used by the Server. Check your webroot/index.php to see it:
// Bind your application to the server.
$server = new Server(new Application(dirname(__DIR__) . '/config'));
// Run the request/response through the application
// and emit the response.
$server->emit($server->run());

Cake PHP3 validate rest API header parameters

I'm developing REST API with cake PHP3 for the mobile application.
Every request header has custom parameter call X-App-Key for the verify mobile app. (Unique ID for the app - X-App-Key : '123456789')
I need to check that parameter value before give access to API endpoints.
How do it check from bootstrap.php or any other place. (in controllers).
Can this use cakephp Dispatcher Filters for validate and filter requests ?
Yes Dispatch Filters would be a good option here. If your application is going to serve browser requests as well, controller would be better. For Dispatch Filters, you can do it like :
1) config\bootstrap.php
DispatcherFactory::add('ApiHeader');
2) src\Routing\Filter\ApiHeaderFilter.php
namespace App\Routing\Filter;
use Cake\Event\Event;
use Cake\Routing\DispatcherFilter;
class ApiHeaderFilter extends DispatcherFilter
{
public function beforeDispatch(Event $event)
{
$request = $event->data['request'];
$xAppKey = $request->header('X-App-Key');
if ($xAppKey != '123456789') {
// throw exception or message
exit;
}
}
}
You can also use TableRegistery for database query :
use Cake\ORM\TableRegistry;
...
$tableModel = TableRegistry::get('table_name');
$xAppKeys = $tableModel->find('all', ...
Reference Links :
Request Headers &
Dispatch Filters

Zend setting the authorization header for unit testing using PHPUnit

Recently I tried to test my REST API's using PHPUnit.
I am facing problem to send http authorization header for my test case.
Every time I do that I get an 403 response instead of 200
Here is my code :
<?php
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use Zend\Http\Request;
use Zend\Http\Headers;
use Zend\Http\Response;
class TrialTest extends AbstractHttpControllerTestCase
{
protected $traceError = true;
public function setUp()
{
$this->setApplicationConfig(
include 'config/application.config.php'
);
parent::setUp();
}
public function testAction()
{
$this->request = new Request();
$this->getRequest()->setMethod('GET');
//$headers = new \Zend\Http\Headers;
//$header = $headers->addHeader($headers->fromString('Authorization:Bearer test'));
$this->getRequest()->sendHeaders('Authorization:Bearer test');
//var_dump($headers);
//$this->getRequest()->setHeaders($header);
$this->dispatch('/campaign');
$this->assertResponseStatusCode(200);
}
}
Kindly help !! where am I going wrong ?
Try setting your headers like this:
$headers = new \Zend\Http\Headers;
$headers->addHeaderLine('Authorization', 'Bearer test');
$this->request->setHeaders($headers);
And you have to make sure that test a valid OAuth token otherwise it will never work. I am not so sure if a 4 character token will ever validate correctly...
UPDATE
I think there is a general problem with your test design. You only set the request object in the controller instance, but the service taking care of authentication has no access to this request object and thus it will not authorize the request correctly.
If you write a controller test in which you test the route '/campaign' you should only test the controller functionality and set mocks for all dependencies. I think the main problem starts in your setUp method. To test this controller you should not load your whole application.config.php. You should set an MvcEvent instance and attach all you need to this event (the correct Router instance, etc) and then dispatch the controller.
Check a proper example of such a ZF2 controller test here.
Testing your OAuth module should happen in an independent test.

Specifying SOAP Headers for a Zend_Soap Service

I have a generally straight forward web service that I've written (converting code to ZF from a Java implementation of the same service and trying to maintain the same wsdl structure as much as possible). The service loads a PHP class, rather than individual functions. The PHP class contains three different functions within it.
Everything seems to be working just fine, except that I can't seem to figure out how to specify that a given function parameter should be passed as a SOAP header. I've not seen any mention of SOAP headers in the Server context, only how to pass header parameters with a client to a server.
In addition to the standard parameters for the function that would be sent in the SOAP body and detailed in the docblock, I would like to specify two parameters (a username and password) that would be sent in a SOAP header.
I have to assume this is possible, but haven't been able to find anything online, nor have I had any responses to a similar post on Zend's forum. Is there something that can be added in the docblock area to specify a parameter as a header (maybe in a similar fashion to using WebParam?)? Any suggestions/examples on how to get this accomplished would be greatly appreciated!
I just ran into this problem myself. My SOAP request is structured like so:
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
<Header>
<APIKey>$key</APIKey>
<SiteID>$id</SiteID>
</Header>
</SOAP-ENV:HEADER>
(body)
</SOAP-ENV:Envelope>
Because the contents of my <SOAP-ENV:Header> tag are in the <Header> enclosure, I created a public method in the class my SoapServer instance loads called Header that then sets a private class variable to true if the API key and Site ID are valid. The other methods in my class that process the body of the request then check to see if that variable is true before proceeding. Ugly, I know, but as you mention, there's no documentation, and this seems to be the easiest way. It looks like this:
class MySoapRequestHandler
{
private $authenticated;
public function Header($data)
{
//your logic here
if($request_is_valid)
{
$this->authenticated = true;
}
else
{
$this->authenticated = false;
}
}
public function ProcessBody($data) //of course named whatever your body element is named
{
if($this->authenticated === true)
{
//process the request
}
else
{
//throw a soap fault?
}
}
}
Let me know if you have more questions; happy to help as much as I can.

Categories