Laravel serving assets insecurely with AWS - laravel

With my new project, when I deploy my app to my https:// domain, every {{ asset() }} and every {{ route() }} is being served over http (which causes "mixed content" security issues in browsers).
I'm using AWS with a load-balanced Elastic Beanstalk application.
I've tried ensuring APP_URL is correctly set to https, and I understand I can use secure_asset or forceScheme, however I didn't have to do this with my previous project and I want to understand why.
How can I see where Laravel is making a decision about protocol? I want to get to the root of the problem rather than plaster over it.

This is an easy gotcha. If you're using AWS you need to change your config. It's very simple and, as usual, Laravel's documentation has the solution. You can read more here:
https://laravel.com/docs/5.6/requests#configuring-trusted-proxies
All I had to do (as an AWS Elastic Beanstalk user) was edit app/Http/Middleware/TrustProxies.php:
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* #var array
*/
protected $proxies = '*';
/**
* The headers that should be used to detect proxies.
*
* #var int
*/
protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
}
Now everything is fine. Easy to miss when setting up a new project.

I believe secure_asset is what you're looking for.
Here an example:
<link href="{{ secure_asset('assets/mdi/css/materialdesignicons.min.css') }}" media="all" rel="stylesheet" type="text/css" />
Update:
A better solution to do it right (tested in laravel 5.4):
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
if(env('APP_ENV') == 'production') {
\URL::forceScheme('https');
}
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}

Related

How to overcome repeative blade component queries in laravel

As in laravel we make blade component to reuse that on multiple pages. so for example we have a cardcomponent that has a query in render function
User::count();
and we use that card component on almost every page so whenever a page is loaded the above query is executed again and again. is there a way to overcome it?
You can put the query in the AppServiceProvider as shown in the documentation here https://laravel.com/docs/9.x/views#sharing-data-with-all-views. The result will be available in all views and the query should only be executed once.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
View::share('key', 'value');
}
}
Alternatively you can use a blade component: https://laravel.com/docs/9.x/blade#components

How to use the Worpress session outside folder in Laravel

I am facing trouble to get the current user login detail in Laravel from WordPress
My Directory Structure
/public_html/
/public_html/ here is all Laravel files like app, route, resources etc.
/public_html/shop/ here is the all WordPress Files
I was using the Service provider for load the wp-load.php files but when I call it its through me error i.e
Cannot redeclare __() (previously declared in /public_html/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:851)
WordPressServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use URL;
class WordPressServiceProvider extends ServiceProvider
{
/**
* Path to our WP installation
*
* #var string
*/
protected $bootstrapFilePath = '..\shop\wp-load.php';
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//echo 'SESSION => '.is_user_logged_in();
/**
* Here we can enqueue any extra scripts or styles we may need.
* I loaded my frontend specific styles and scripts that were of no use to the WP site
*/
//wp_enqueue_style('frontend-styles', URL::asset('css/frontend.css'), ['dependencies'], false);
//wp_enqueue_script('frontend-scripts', URL::asset('js/frontend.js'), ['dependencies'], false, true);
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
if(\File::exists($this->bootstrapFilePath)) {
//echo 'INSIDE REGISTER';
require_once($this->bootstrapFilePath);
}else{
//echo 'OUTSIDE REGISTER'.$this->bootstrapFilePath;
}
}
}

Google Cloud Kubernetes Laravel Get Visitor IP

I'm trying to get visitor IP on my Laravel application that uses Nginx on Google Cloud Kubernetes Engine, under load balancer.
I have set up TrustProxies.php like this:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* #var array
*/
protected $proxies = '*';
/**
* The headers that should be used to detect proxies.
*
* #var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
I have also tried
protected $proxies = '**';
And
protected $proxies = ['loadbalancer_ip_here'];
No matter what I have tried, it will always return load balancer ip.
Might this be caused by Nginx configuration? Help appreciated.
You have to set traffic policy in your nginx service
externalTrafficPolicy: "Local"
and also
healthCheckNodePort: "numeric port number for the service"
More details in Preserving the client source IP doc

Laravel Testing Request - Service Provider - Middleware Issue

I have a Laravel 5.5 App where I have a Service Provider which I use to put some stuff in the request->attributes to access it everywhere (simplified):
namespace App\Providers;
use App\Models\Domain;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class GlobalVarsServiceProvider extends ServiceProvider
{
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap the application services.
*
* #param Request $request
*
* #return void
*/
public function boot(Request $request)
{
$domain = .. get domain with language and some logic and cache because of multiple domains ..
$request->attributes->add(['domain' => $domain]);
}
}
I do this in a Service Provider, because then I can already use it in other Service Providers like my ViewComposerServiceProvider, where I compose some stuff for the Views. I'm able to access $domain everywhere like this:
$this->domain = $request->attributes->get('domain');
It works great. BUT not in testing. When I want to access $domain in a Unit Test in a middleware the $request->attributes are empty (In UnitTests as in DuskTests either).
It looks like the testing environment uses a different Request Lifecycle? If yes, what else is different in the testing environment?
What am I doing wrong?
-- Edit --
Test Example:
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
TestCase uses trait MakesHttpRequests which has method call. When you use get method in your tests, it's simply a shortcut to this.
In your test you can use it like this:
$this->call('GET', '/url/here', $yourRequestParametersHere);

Laravel Architecture - Event vs. Controller

My question is related more about the architecture of an Laravel application. I'm developing an application and I have some problems about the positioning of my codes. Let's assume I have a controller to control the comments of my post, but now, after a while, I need to add an action each time a comment is registered, in this case, I create an event or simply add this new action to my controller action?
Thank you.
As Bogdan's says, you should read Model Events.
A sample approach could be the next.
Create a service provider:
php artisan make:provider CommentServiceProvider
Then a sample CommentServiceProvider class:
<?php
namespace App\Providers;
use App\Comment;
use Illuminate\Support\ServiceProvider;
class CommentServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Comment::creating(function ($comment) {
//... do stuff here
});
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}

Resources