Header not allowed on the server? - php

I have a simple API in Laravel. The routes file is like so:
<?php
Route::resource('airports', 'AirportController');
Route::resource('flights', 'FlightController');
Route::resource('reservations', 'ReservationController');
Route::get('auth', 'AuthController#index');
Route::post('auth', 'AuthController#store');
Route::delete('auth', 'AuthController#destroy');
The filter's file has a custom filter added like so:
Route::filter('auth_token', function()
{
$auth_token = Request::header('Authorization');
if(!AuthToken::where('auth_token', '=', $auth_token)->first()){
return Response::json([], 401);
}
});
All the resources need to pass before the auth_token filter. Now this works great on my local machine but as soon as I try it on my server, everything is unauthorized, even if I pass a valid token. The problem I figured by dd($auth_token) in my custom filter is that it is returning null which means that my server is not accepting the header for some reason.
My .htaccess file looks like so:
<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]
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "*"
</IfModule>
I am using Postman REST client to test my application. There is only one user in the system with email 'admin#admin.com' and password 'admin12345'. You can POST these details to the /auth route and get an access token granted which can then be used to fetch other resources in the system.
The application is hosted here. What am I doing wrong?

The order of the routes might be an issue. try inverting like this and see if it works ...
Route::get('auth', 'AuthController#index');
Route::post('auth', 'AuthController#store');
Route::delete('auth', 'AuthController#destroy');
Route::resource('airports', 'AirportController');
Route::resource('flights', 'FlightController');
Route::resource('reservations', 'ReservationController');

Related

how to keep session data when redirect to external url in laravel

I am new on PHP. I have a laravel api and laravel webui in different servers. When i make a request for login in webui, sent it to api and if result is success return laravel/passport token to webui. I stored token in session(in webui auth controller).
AuthController;
Session::put('token', $value['token']);
My CustomAuth Middleware;
class CustomAuth extends Middleware {
public function handle($request, Closure $next, $guard = null){
if (Session::has('token')) {
return $next($request);
} else {
return response(view('pages.unauthorized'));
}
}
}
Payment method;
return redirect()->away($redirectUrl);
And then, when payment is success/fail wirecard returning to my site(callbackUrl). In this section, session data is lost and user redirect to login page. I am not sure whether I am wrong in the auth part or use the session incorrectly. Can i store session data when i redirect? Or how can i change auth part?
Note: success and fail routes has to be in auth middleware. And my all routes in web middleware group. In app/Http/Kernel.php, this line added in 'web'
\Illuminate\Session\Middleware\StartSession::class,
Ideally when you are building an API, we are not using web middleware group but api middleware group. Thus if all your routes are in api.php(they should be here) then the session is not activated or it won't work because you are using api middleware group and api guard here.
Another thing is, you have already generated a token using passport so you don't need to store the token in session. That's the awesome thing about Json Web Token. It can be parsed when your WebUI pass the token back to backend. The backend/API can just look at it and see if the token is authenticated, no need to check session or anything like that when you are handling token. To do so you have to pass through auth:api middleware for your api routes.
Lastly, you have to make sure that the WebUI is sending back the token in correct form(e.g. Bearer header, basic auth etc.).
Good luck!
One possible solution:
when working with payment callback you should always remember the session data for addreses including https, http, www and none-www are different.
You should always always force (www or none-www) and (https or http). in this way you can always be sure that user will always come back to the address that user session data is stored.
according to web server you are using, the approach to do this will be different.
for example if you are using apache, you can use following config in htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# remove wwww.
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]
# redirect to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Get the value which comes after the domain name in laravel

how to create route in laravel for the below 2nd option....
http://localhost:8048/
http://localhost:8048/content/645668/nice-up-civic-poll.html
1st it redirects to home page which is correct for me.
2nd I need to get what ever comes after 8048/
so basically content/645668/nice-up-civic-poll.html is a parameter which I need to deal with it separately and its dynamic link.
Route api in laravel :
Route::get('/', 'HomeController#index');
www.example.com will load home page with all stories.
The below links as an example should get the value after www.example.com/ basically its a story/article link so when that comes specific story will be displayed.
www.example.com/content/645668/nice-up-civic-poll.html
www.example.com/content/283206/something-here.html
www.example.com/content/234323/good-nice.html
www.example.com/content/451425/breakup-actor.html
www.example.com/content/365412/accident-occured.html
So basically get everything after domain name which is using apache server.
.htaccess file
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
If you want a home route and then every other URI to go to a single Controller method you can make a catch-all route:
Route::get('{catch}', 'SomeController#action')->where('catch', '.*');
This would catch any URI that doesn't match any previously defined route.
If you want everything to go to one place:
Route::get('{catch?}', ....)->where(...); // optional param
Post about creating a catch all route, answer using regex conditions on parameter:
SO - How do I make a Catch-All Route in Laravel 5.2
Update:
If these URIs you need to catch all have the same format,
www.example.com/content/645668/nice-up-civic-poll.html
you can register a route to match that format instead of catching everything possible:
Route::get('content/{id}/{slug}', function ($id, $slug) {
...
});
try using $request helper..
$leftbehind = str_replace($request->getHost(),'', $request->fullUrl());
or try this..
$request->getRequestUri();
Use $request->path()
The path method returns the request's path information. So, if the incoming request is targeted at http://example.com/foo/bar, the path method will return foo/bar
https://laravel.com/docs/5.5/requests#request-path-and-method
You can use The Request::path() to get the current url.
https://laravel.com/api/5.5/Illuminate/Http/Request.html - Check this for all the options available for Request.
eg: If you want to just check whether the users is in some url or not use this - Request::is('/url') // This will return true or false
You can use php's built in function, parse_url to retrieve content/645668/nice-up-civic-poll.html.
parse_url($url, PHP_URL_PATH)

Laravel remote server error 500, site doesn't works

It's my first upload to a remote server of a Laravel site.
Local I have configured a vhost so my access to my site is like:
site.domain.com //it's pointing htdocs/laravel-proyect/public
I have uploaded my site to my remote server, then:
Change permisions on storage and all its directories
Change permisions to bootstrap
Change configuration of app.php
'url' => 'http://site.domain.com',
Change configuration in database.app with new parameters (as well as in email.php)
Load all tables and data in the data base
Then I try to load my site and get a 500 Internal Server Error
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
It works a little, I have this code in routes.php:
// Begins in the login view
Route::get('/', function()
{
if (!Sentry::check()) {
$data = array();
if (Session::has('email')) {
$data = array('email' => Session::get('email'));
}
return Redirect::route('login', $data);
}
else
return Redirect::route('users');
});
/ ========================================
// LOGIN, LOGOUT AND ACTIVATION SECTION ==========
// // ============================================
// show the login page
Route::get(MyHelpers::textLang('login','routes'), array('as' => 'login', function()
{
if (Sentry::check())return Redirect::route('users');
else {
$rules = User::$rules_login;
// show the login page (app/views/frontend/login.blade.php)
return View::make('frontend.login', compact('rules'));
}
So at first time mo url look like:
site.domain.com/entrar
'entrar', (login in spanish), y set by MyHelpers::textLang('login','routes'), access to my class MyHelpers and to lang files to translate 'login' in to 'entrar', but dont load the template.
Begins to :
Read documentation, making some changes: deleting Multiviews from
.htaccess (deprecated), adding RewriteBase to .htaccess too.
Copy /public content to base dir and change paths in bootstrap/paths and
in the index.php files.
Reinstall in two remote servers to verify is not my provider failing (same error). Talking to my provider, supouse
there are no errors on the server.
I create a new htaccess in the base dir redirecting routes to /public.
Try with php 5.4, 5.5 and 5.6
Actually my .htaccess is:
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]
And I have no more ideas and cant find other solutions as related here.
Any idea? Please, I'm getting crazy, on wensday I have to beguin a new proyect and still working with this one.
Thanks
I have to add
RewriteBase /
to the .htaccess
I have a demo laravel application on heroku Simple Blog.My .htaccess file is:
<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>
#other lines for gzip
It seems that there is no issue with your .htaccess file. It may be problem with you code logic. If you are getting no error with same code on localhost, then check your config again. For laravel 4, there is already a similar issue on stackoverflow Laravel 4 Virtual Host and mod rewrite setup
Note that laravel 5 (if you are using it) takes input (database connection and other setting) from .env file.
If you are still getting error then try to send simple response on index page like:
Route::get('/','basic configurations are correct');
and then make it complex step by step. It will help you in finding error.
Answer from #kikerrobles really works.
your final .htaccess file should look like following
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteBase /
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Laravel route directing to Home instead of throwing a NotFoundHttpException

I'm experiencing some unexpected behaviour in my laravel (4.2) routes.
Let's say my server is available at https://example.com. If I enter https://example.com/whatever/index.php I would expect laravel to throw a NotFoundHttpException, because a route to "whatever" is not defined. Instead laravel shows me the start page, indicating that my "home" route was catched.
If I solely enter https://example.com/whatever everything is fine (i.e. I get the NotFoundHttpException as expected). I neither have the problem on my localhost. Here https://localhost/laravel/whatever/index.php throws the NotFoundHttpException as expected.
My routes.php file:
// Home
Route::get('/', array( 'as' => 'home', function() {
return View::make('home');
}));
Maybe someone can give me a hint where to start searching what's causing that behaviour: Apache config, PHP config, Laravel config?
Ammendment as answer to S. Safdar:
At first I thought of a .htaccess redirect issue, too. In laravel's public folder (the web servers root dir) lays a .htaccess as follows:
<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>
As you can see, the redirect here is handled correctly. The requested "whatever/index.php" is no real file therefore it is redirected to be handled by laravels index.php. If I remove the Rewrite Conditions (plus Rule) I get a regular apache 404 error page. In my case that's of no help as I want laravel to correctly(!) handle all error pages. But for some reason laravels home route matches every url ending on /index.php.
It seems this issue is present with both nginx and apache servers. A few steps I took to mitigate the issue with apache:
Change the index.php filename:
public/index.php to public/start.php
Change .htaccess to read:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ start.php [L]
Change the reference to index.php in the server.php file to have:
require_once $paths['public'].'/start.php';
why not you your route use this like?
// Home
Route::get('/', function() {
return View::make('home');
}));
i think problem is coming from as that you used in your route array.

Laravel get request headers

I am using POSTMAN to send a GET request into the api with a header containing Authorization.
I know the data header works because if it doesn't the route returns a 401 error.
I wanted to get the Authorization header like so:
$access_token = Request::header('Authorization');
But noticed that it returns NULL.
So I tried to catch the values with:
die(var_dump(Request::header()));
And noticed that it doesn't contain any Authorization header. Just host to cookie headers.
update
Should get Authorization: Bearer ACCESS TOKEN
What POSTMAN Version did you use?
Are you on your local machine or managed server, some hosting companies don't allow AUTHORIZATION HEADER.
.htaccess modification
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
The answer from dschniepp is right, but I have problems with this too. You have to do two things:
Check if mod_rewrite is available and activated.
Update the .htaccess file of Laravel, located in the public folder.
In the first point you have to check if the "mod_rewrite" module is available through php_info function, in a separate php file. Then if it is available you have to activate it, that depends on the configuration of your webserver, in my Nitrous box I added these lines to my httpd.conf file:
<IfModule mod_rewrite>
RewriteEngine On
</IfModule>
Or you can activate the module in the .htaccess file too:
RewriteEngine On
Then in the same .htaccess file located in public folder in the root of the laravel app, you have to add these lines:
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
These lines worked for me. Your .htaccess file should look like this:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
And that's it, you should have the Authorization header in the Request::header() array. Just to clarify these is an issue with Apache, not with Laravel itself.
In Laravel 5.5 you can read herders by using apache_request_headers simply read it in your controller by the following lines
$headers = apache_request_headers();
dd($headers['Authorization']);
Make sure you have added use Illuminate\Http\Request; in your controller
Missing authorization headers with Apache virtual host.
Apart of the solution above the culprit may be because Apache server does not allow authorization header to pass through virtual host.
To solve this issue you have to add the line allowing Apache to pass authorization header to PHP in you virtual hosts configuration. E.g. for Ubuntu 18.04 the virtual host is defined in /etc/apache2/sites-available/your-site-name.conf, see this tutorial for better context.
<VirtualHost>
# ...
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# ...
</VirtualHost>
After updating the virtual host config do not forget to restart Apache (again e.g. Ubuntu 18.04 sudo systemctl restart apache2).
This should fix the issue.
Here is the original answer.
Posting this here as it solved my problem. This applies for sub domains but can obviously be adjusted for plain domains as well. Applied this within my routes file at the top.
$newUrl = '';
try{
$urlParts = parse_url($_SERVER['HTTP_REFERER']) ?? '';
$newUrl = $urlParts['scheme'] . "://" . $urlParts['host'];
if(!stristr($newUrl, '.yourdomain.com')){
$newUrl = 'false';
}
}catch(Exception $e)
{}
header('Access-Control-Allow-Origin: ' . $newUrl);
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: access-control-allow-origin,cache-control,content-type,postman-token');

Categories