ignaaaam's avatar

If someone submits a link without https force it

Hi i'm making a website for people being able to upload discounts. If someone inputs a link without https then the link opens in the same app url (localhost:3000/link) how should I force so everylink has an https:// even if they dont type it or not adding anything if they include it? It must be done in validation?

DiscountController

<?php

namespace App\Http\Controllers;

use App\Models\Category;
use App\Models\Discount;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class UserDiscountController extends Controller
{
    public function index()
    {
        $discounts = auth()->user()->discounts()->orderBy('created_at','desc')->paginate(5);

        return view('users.discounts.index', [
            'discounts' => $discounts
        ]);
    }

    public function create()
    {
        $categories = Category::all();
        return view('users.discounts.create', [
            'categories' => $categories
        ]);
    }

    public function store()
    {
        $originalPrice = request('original_price');
        $discountedPrice = request('discounted_price');
        $percentage = 100 * ($originalPrice - $discountedPrice) / $originalPrice;

        Discount::create(array_merge($this->validateDiscount(), [
            'user_id' => request()->user()->id,
            'thumbnail' => request()->file('thumbnail')->store('discount_thumbnails'),
            'percentage' => $percentage
        ]));

        return redirect('/');
    }


    protected function validateDiscount(?Discount $discount = null): array
    {
        $discount ??= new Discount();
        $originalPrice = request('original_price');
        $discountedPrice = request('discounted_price');
        $percentage = 100 * ($originalPrice - $discountedPrice) / $originalPrice;

        return request()->validate([
            'title' => 'required',
            'thumbnail' => $discount->exists ? ['image'] : ['required', 'image'],
            'slug' => ['required', Rule::unique('discounts', 'slug')->ignore($discount)],
            'body' => 'required',
            'original_price' => 'required|numeric|gt:discounted_price',
            'discounted_price' => 'required|numeric|lt:original_price',
            'category_id' => ['required', Rule::exists('categories', 'id')],
            'link' => 'required',
        ]);

    }
}

create.blade.php

<x-layout>
    <x-setting heading="Crear mi descuento">
        <form action="/user/discounts" method="POST" enctype="multipart/form-data">
            @csrf

            <x-form.input name="title" />
            <x-form.input name="slug" />
            <x-form.input name="thumbnail" type="file" />
            <x-form.input name="original_price" type="number" step="any" />
            <x-form.input name="discounted_price" type="number" step="any" />
            <x-form.input name="link" />
            @if(auth()->user()->role_id == 1 || auth()->user()->role_id == 3)
                <x-form.checkbox name="premium"/>
            @endif
            <x-form.textarea name="body" />

            <x-form.field>
                <x-form.label name="category" />
                <select name="category_id" id="category_id" class="border border-gray-400 p-2 rounded">

                    @foreach($categories as $category)
                        <option value="{{ $category->id }}">{{$category->name}}</option>
                    @endforeach
                </select>

                <x-form.error name="category" />
            </x-form.field>

            <x-form.button>Publicar</x-form.button>
            @if($errors->any())
                {{ implode('', $errors->all('<div>:message</div>')) }}
            @endif
        </form>
    </x-setting>
</x-layout>

Adding a discount works. The problem is that if someone inputs for example www.google.com as a link it doesnt open as a link. I should add something that adds the https:// at start if they dont add anything or leave it as it is if they add it.

0 likes
7 replies
Niush's avatar

This can be added in Nginx/Apache web server configuration. To redirect http to https.

And, if you want to do from Laravel. You can add this to your boot method of AppServiceProvider.php.

if($this->app->environment('production')) {
    \Illuminate\Support\Facades\URL::forceScheme('https');
}

Then, better use route() helper with named route instead. Example:

<form action="{{ route('users.discounts') }}".....
ignaaaam's avatar

@Niush But im not talking about my app url, im talking about the link that a user inputs into a new discount.

Niush's avatar
Niush
Best Answer
Level 50

@ignaaaam Sorry. For that use case, you should first validate the link with Laravel. Using url and/or active_url rules.

Then, you could do something like this:

// request()->input('link') = www.example.com/get-discount?ref=xyz

request()->validate([
    'link' => ['required', 'url', 'active_url']
]);

$link = parse_url(request()->input('link'), PHP_URL_SCHEME)
			? request()->input('link')
			: 'https://' . request()->input('link')
1 like
tykus's avatar

Rather than modifying the user-submitted data; use validation to ensure you get the correct data.

You can use active-url to ensure you get a valid A or AAAA record.

Snapey's avatar

you can use the string helper startsWith

if it does not start with 'http' then prefix with 'http://'

you cannot know if the site has https so add http - most sites will redirect if https is available

iftekhs's avatar

You can use middleware ->

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class secureHttps
{
    public function handle(Request $request, Closure $next)
    {

        if (!$request->secure() && App::environment() === 'production') {
            return redirect()->secure($request->getRequestUri());
        }

        return $next($request);
    }
}

Kernal.php ->

 protected $middleware = [
        \App\Http\Middleware\secureHttps::class,
    ];

Please or to participate in this conversation.