Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing Authorization Header in request->getHeaders() on MAMP #6631

Closed
nadar opened this issue Dec 23, 2014 · 25 comments
Closed

Missing Authorization Header in request->getHeaders() on MAMP #6631

nadar opened this issue Dec 23, 2014 · 25 comments

Comments

@nadar
Copy link
Contributor

nadar commented Dec 23, 2014

Case:
We are currently building a Yii2 Rest Application, which is access trough an Angular application. We have applied the authToken in a authInterceptor the verify the user who makes the request.

request : function (config) {
        config.headers = config.headers || {};
        config.headers.Authorization = 'Bearer ' + authToken;
        return config;
    }

Problem:
The "Authorization Header" is not provided when using Yii2 Rest on a MAMP Server. The function getallheaders() in yii2\web\Request->getHeaders() does not return this Header entry. On an ubuntu server (for instance) it works like a charm, but not on every webserver configuration. Is there a workaround? Although, you should probably mention that in your Guide to use the correct Server Configuration (http://www.yiiframework.com/doc-2.0/guide-rest-authentication.html).

regards

@samdark
Copy link
Member

samdark commented Dec 23, 2014

So yii2\web\Request->getHeaders() returns no data on particular server setup (MAMP)?

@nadar
Copy link
Contributor Author

nadar commented Dec 23, 2014

It does return data. But the requested Authorization parameter, which is required in the bearer auth filter, is missing.

$authHeader = $request->getHeaders()->get('Authorization');

from:
https://github.com/yiisoft/yii2/blob/master/framework/filters/auth/HttpBearerAuth.php

public function authenticate($user, $request, $response)
    {
        $authHeader = $request->getHeaders()->get('Authorization');
        if ($authHeader !== null && preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)) {
            $identity = $user->loginByAccessToken($matches[1], get_class($this));
            if ($identity === null) {
                $this->handleFailure($response);
            }
            return $identity;
        }
        return null;
    }

And as i could see, getHeaders() collects data from the function getallheaders(), i have debuged the output from getallheaders() and could have seen that Authorization parameter is not provided (at least on the mamp server installation).

from:
https://github.com/yiisoft/yii2/blob/master/framework/web/Request.php

 public function getHeaders()
    {
        if ($this->_headers === null) {
            $this->_headers = new HeaderCollection;
            if (function_exists('getallheaders')) {
                $headers = getallheaders();
            } elseif (function_exists('http_get_request_headers')) {
                $headers = http_get_request_headers();
            } else {
                foreach ($_SERVER as $name => $value) {
                    if (strncmp($name, 'HTTP_', 5) === 0) {
                        $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
                        $this->_headers->add($name, $value);
                    }
                }
                return $this->_headers;
            }
            foreach ($headers as $name => $value) {
                $this->_headers->add($name, $value);
            }
        }
        return $this->_headers;
    }

@qiangxue
Copy link
Member

I think you should consult with MAMP support or google it for solution. This is not Yii-specific issue.

@nadar
Copy link
Contributor Author

nadar commented Dec 23, 2014

I'll do some research on this issue and post back what i've found. If the problem appears to other people, you could mention it in your guide.

@samdark
Copy link
Member

samdark commented Dec 23, 2014

Will wait for research results. Currently it's not clear why it happens and how to fix it.

@nadar
Copy link
Contributor Author

nadar commented Jan 20, 2015

We have fixed the problem. The problem appears if you'r using CGI/FastCGI mode. As mentioned in the php comments (http://php.net/manual/en/features.http-auth.php#114877) you can put

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

in the .htaccess file to make Authorizaion variable available.

@woody1ks
Copy link

woody1ks commented Feb 6, 2015

@nadar Two thumbs up for the solution. Inside MAMP Pro for those people using it, you need to switch back to Module Mode Under the PHP Tab, by selecting the Mode radio underneath PHP default version labeled as "Identical PHP version for all hosts (module)" if you choose to not edit the .htacess file.

Thank you again for the solution with CGI!

@alagodich
Copy link

If you are using https://github.com/bshaffer/oauth2-server-php
You can also take a look at this comment:
https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Request.php#L138

@gauravparashar12
Copy link

I am also facing a similar problem in my code. When I am working on my localhost then my code works perfect and i am getting the authorization in my headers varible as all the required headers are there, but issue comes when I hit the API from another origin as I look into the headers "authorization" header is missing in headers variable when I compare it to previous scenario.

@nadar
Copy link
Contributor Author

nadar commented Oct 15, 2015

@gauravparashar12 Try to add:

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

to your .htaccess file.

@gauravparashar12
Copy link

@nadar Yes i added in the root .htacces but its not working and when i apply the condition on $authHeader in autheticate function in HttpBearerAuth class its working but i dont know why and how .
My modified function is:
public function authenticate($user, $request, $response)
{

   $authHeader = $request->getHeaders()->get('Authorization');
   if(empty($authHeader)) {
        exit();
   }
   if ($authHeader !== null && preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)) {
        $identity = $user->loginByAccessToken($matches[1], get_class($this));
        if ($identity === null) {
            $this->handleFailure($response);
        }
        return $identity;
    }

    return null;
}

Hack is :
if(empty($authHeader)) {
exit();
}

As I am debugging this issue I found the same request is made from angular two time, first without Authorization and second with Authorization. Do you have any idea regarding this?

@nadar
Copy link
Contributor Author

nadar commented Oct 15, 2015

On which environment are you running your code/application?

  • linux/win/mac?
  • webserver?
  • enabled modules?

@gauravparashar12
Copy link

on window 7
apache

config file are

getBaseUrl()); $config = [ 'components' => [ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => 'z9NT8BJ3dFGhwqyISaHxsGQJWPc04dO_gsdfgsdf', 'baseUrl' => $baseUrl, 'parsers' => [ 'application/json' => 'yii\web\JsonParser', ] ], 'user' => [ 'identityClass' => 'common\models\User', 'enableSession' => false, 'loginUrl' => null, 'enableAutoLogin' => false, 'identityCookie' => [ 'name' => '_frontendUser', // unique for backend 'path'=>'/lbp/frontend/web' // correct path for the backend app. ] ], 'session' => [ 'name' => 'PHPFRONTSESSID', 'savePath' => __DIR__ . '/../tmp', ], 'response' => [ 'class' => 'yii\web\Response', 'on beforeSend' => function ($event) { $response = $event->sender; if ($response->data !== null && Yii::$app->request->get('suppress_response_code')) { $response->data = [ 'success' => $response->isSuccessful, 'data' => $response->data, ]; $response->statusCode = 200; } }, ], 'urlManager' => [ 'class' => 'yii\web\UrlManager', 'baseUrl' => $baseUrl, 'enablePrettyUrl' => true, 'showScriptName' => false, //'enableStrictParsing' => true, 'rules' => [ ['class' => 'yii\rest\UrlRule', 'controller' =>['profile'], 'pluralize'=>false], ], ``` ], 'urlManagerBackEnd' => [ 'class' => 'yii\web\urlManager', 'baseUrl' => '/lbp/backend/web/', 'enablePrettyUrl' => true, 'showScriptName' => false, ], ], 'as access' => [ 'class' => 'mdm\admin\components\AccessControl', 'allowActions' => [ 'home/*', 'api/*', 'events/index', 'events/view', 'news/index', 'news/view', 'post/post-detail', 'categories/view-by-slug', 'pages/*', 'guestbook/*', // The actions listed here will be allowed to everyone including guests. // So, 'admin/*' should not appear here in the production, of course. // But in the earlier stages of your development, you may probably want to // add a lot of actions here until you finally completed setting up rbac, // otherwise you may not even take a first step. ] ] ``` ]; if (!YII_ENV_TEST) { // configuration adjustments for 'dev' environment $config['bootstrap'][] = 'debug'; $config['modules']['debug'] = 'yii\debug\Module'; ``` $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = 'yii\gii\Module'; ``` } return $config; .htaccess file Options -Indexes RewriteEngine on SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0 RewriteCond %{REQUEST_URI} !app RewriteCond %{REQUEST_URI} !media RewriteRule ^(.*)$ frontend/web/$1 [L] # Deny accessing below extensions Order allow,deny Deny from all # Deny accessing dot files RewriteRule (^.|/.) - [F]

@nadar
Copy link
Contributor Author

nadar commented Oct 15, 2015

@gauravparashar12 better send me a mail. We will post the solution back here if its related to the starting topic.

@jhebb
Copy link

jhebb commented Feb 16, 2016

@nadar Your fix worked perfectly for me, thanks!

@brucco
Copy link

brucco commented May 6, 2016

@nadar Your fix...

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

worked for me like a charm. +1 to you - saved me lots of headaches I'm sure.

Using Godaddy shared hosting with php 5.5.

@desaikalpesh34
Copy link

Thanks @nadar its working...

@kishoreTechO2
Copy link

@nadar
How to set the SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0 in the nginx web server?

@nadar
Copy link
Contributor Author

nadar commented Feb 3, 2017

Maybe this works:

fastcgi_pass_header Authorization;

@nye
Copy link

nye commented Feb 10, 2017

Just adding SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0 to .htaccess didn't worked for me.

But following this article worked well!

https://chrislee.kr/wp/2017/01/06/missing-authroization-header-in-request/

;)

@fangj99
Copy link

fangj99 commented Nov 3, 2017

Tried all the methods you guys provided, but none of them working, then I directly copied yii2 2.0.10's vendor/yiisoft folder to overwrite the currently 2.0.11's vendor/yiisoft , it is working now.

It seems 2.0.11's change make Rest API not getting correct access token

Tried on 3 Centos 7 servers with nginx, php5/php7 and localhost, all the same result.

Do not forget to keep the original vendor/yiisoft/extensions.php or your installed plugins will be missing

Hope this will help!

@samdark
Copy link
Member

samdark commented Nov 3, 2017

@fangj99 have you tried latest stable version?

@fangj99
Copy link

fangj99 commented Nov 3, 2017

@samdark

Tested with 2.0.13, it seems filsh/yii2-oauth2-server and bshaffer/oauth2-server-php plugin are not compatible with 2.0.13

I have pasted error in below:

  1. When using RestAPI try to get token:

exception 'yii\base\ErrorException' with message 'Argument 1 passed to OAuth2\Server::handleTokenRequest() must be an instance of OAuth2\RequestInterface, instance of yii\web\Request given, called in /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/Server.php on line 39 and defined' in /usr/share/nginx/html/dev-work20171103/vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php:298
Stack trace:
#0 /usr/share/nginx/html/dev-work20171103/vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php(298): yii\base\ErrorHandler->handleError(4096, 'Argument 1 pass...', '/usr/share/ngin...', 298, Array)
#1 /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/Server.php(39): OAuth2\Server->handleTokenRequest(Object(yii\web\Request), NULL)
#2 /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/controllers/RestController.php(25): filsh\yii2\oauth2server\Server->handleTokenRequest()
#3 [internal function]: filsh\yii2\oauth2server\controllers\RestController->actionToken()
#4 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#5 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#6 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('token', Array)
#7 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('oauth2/rest/tok...', Array)
#8 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#9 /usr/share/nginx/html/dev-work20171103/frontend/web/index.php(22): yii\base\Application->run()
#10 {main}

  1. When using RestAPI with access token (working token in 2.0.10)
    exception 'yii\base\ErrorException' with message 'Argument 1 passed to OAuth2\Server::verifyResourceRequest() must be an instance of OAuth2\RequestInterface, instance of yii\web\Request given, called in /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/Server.php on line 31 and defined' in /usr/share/nginx/html/dev-work20171103/vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php:398
    Stack trace:
    #0 /usr/share/nginx/html/dev-work20171103/vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php(398): yii\base\ErrorHandler->handleError(4096, 'Argument 1 pass...', '/usr/share/ngin...', 398, Array)
    yii2 现在进行的如何? #1 /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/Server.php(31): OAuth2\Server->verifyResourceRequest(Object(yii\web\Request), NULL, NULL)
    Implement PostgreSQL database driver #2 /usr/share/nginx/html/dev-work20171103/vendor/filsh/yii2-oauth2-server/filters/auth/CompositeAuth.php(17): filsh\yii2\oauth2server\Server->verifyResourceRequest()
    Implement SQLServer database driver #3 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/ActionFilter.php(75): filsh\yii2\oauth2server\filters\auth\CompositeAuth->beforeAction(Object(yii\base\InlineAction))
    Implement Oracle database driver #4 [internal function]: yii\base\ActionFilter->beforeFilter(Object(yii\base\ActionEvent))
    Implement DB2 database driver #5 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Component.php(557): call_user_func(Array, Object(yii\base\ActionEvent))
    Implement requirements checker #6 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
    ArrayHelper::multisort is not compatible with PHP 5.3 #7 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/web/Controller.php(164): yii\base\Controller->beforeAction(Object(yii\base\InlineAction))
    Assets / packages management #8 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Controller.php(155): yii\web\Controller->beforeAction(Object(yii\base\InlineAction))
    Update code style to match what's actually used #9 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('settings', Array)
    Extension should be able to register its own translated messages #10 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('api/v1/data-col...', Array)
    Implement NoSQL Storage for ActiveRecord #11 /usr/share/nginx/html/dev-work20171103/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
    Implement GettextMessageSource #12 /usr/share/nginx/html/dev-work20171103/frontend/web/index.php(22): yii\base\Application->run()
    Implement DbMessageSource #13 {main}

@devexpart
Copy link

We have fixed the problem. The problem appears if you'r using CGI/FastCGI mode. As mentioned in the php comments (http://php.net/manual/en/features.http-auth.php#114877) you can put

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

in the .htaccess file to make Authorizaion variable available.

not working in my case

@mbaliya26
Copy link

mbaliya26 commented Jan 3, 2024

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

add this line in .htaccess file and Working fine

@yiisoft yiisoft locked as resolved and limited conversation to collaborators Jan 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests