4

I have the following piece of code in Laravel BaseController. I want to protect all my api resources with an Authorization header with a token.

  public function __construct()
  {
    $this->beforeFilter('@getUserFromToken');
  }

  public function getUserFromToken($route, $request)
  {
    $accessToken = Request::header('Authorization');
    if(!empty($accessToken)){
      $this->currentUser = User::findByToken($accessToken);
    }else{
      return Request::header('Authorization'); //THE PROBLEM
      return Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403);
    }
  }

Here is my .htaccess if that's relevant.

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

So if I have the marked problem line, Apache will read everything perfectly. And I will get my responses back and not getting the 403. However, if I don't have that line, I will get 403 error with my custom error message. WHY? Obviously I am using the same code $this->currentUser = User::findByToken($accessToken);, why by leaving the marked line I'll be able to get the header? Is there a redirect happening behind the scene that sets the Authorization header somehow only the second time? Is there a setting that I missed for apache to pick up the header the first time?

UPDATE: I guess my question is: if I just return Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403);, I will always get this error json. And my $accessToken will always be empty. Why?

MORE UPDATE: Looks like I shouldn't reuse Authorization Header? I tried:

$accessToken = Request::header('Custom-Token');
if(!empty($accessToken)){
  $this->currentUser = User::findByToken($accessToken);
}else{
  return Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403);
}

And this time I'm able to get the real token. My question still stands then, why can I return the "magical" header and suddenly get it in Laravel?

This related question didn't answer it, but pointed me to the right direction: laravel 4: why is Request::header() not getting the specified header?

One more thing: the Authorization header does work without the magic return if I serve use php artisan serve, which uses php dev server.

0

2 Answers 2

16
+50

It is a Laravel & Apache problem, this line in public/.htaccess fixed it for me:

RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

The fix is from https://github.com/dingo/api/issues/54

Sign up to request clarification or add additional context in comments.

2 Comments

You are an angel. I banged my head for endless hours and could not figure out what went wrong. If it weren't for this answer I would go on using the token in the URL params which is not a clean approach if you ask me. I have raised a bounty and will award it to you as soon as Stack Overflow lets me. Thank you so much. :)
@Rohan. Glad it also helped you. Don't worry about the bounty. Your comment is reward in itself. :)
0

You cannot have two returns in PHP:

return Request::header();
return Response::json();

So in your code, only the header will return, and your code will exit.

I think this will work

return Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403)->header('Authorization');

If not - this definetely will:

$response = Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403);
$response->header('Authorization');
return $response;

4 Comments

I know. I'm only putting that code there while debugging, and somehow found a fix. I would like to do return Response::json(['error'=>'Not authorized. Access token needed in Header.Authorization'], 403); But my question is really why the Authorization value is empty when it came through.
I dont understand what you are asking - please expand on your question with more information.
Not really. Why do you think $accessToken will be magically filled if you return a JSON error?
I don't know why. That's the problem. :) I'm wondering if it's something with apache or my code. Anyway, if I do return 'Your Header.Authorization is: '. $accessToken;, it will always return Your Header.Authorization is: . If I do that "magic" return, I will get the results that I want. But I don't want the "magic" return all the time, only when I really truly don't have a Header.Authorization set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.