vincent15000's avatar

vincent15000 wrote a reply+100 XP

4h ago

Oh effectively ... yes I understand ... well ... I went to this website.

https://securityheaders.com/

The diagnostic was simply that the cookie didn't have any prefix. So I read the documentation about what __Host- is and I thought that it was a good idea to add it ;).

vincent15000's avatar

vincent15000 liked a comment+100 XP

4h ago

@vincent15000 But Laravel cookies are already secure by being HTTP only, optionally HTTPS-only, restricted to path, restricted to domain, and with cross-site restrictions. So what, exactly, “enhanced security” were you trying to add here?

vincent15000's avatar

vincent15000 wrote a reply+100 XP

4h ago

Yes I still get the error after npm run build.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4h ago

I think what @jsanwo64 was suggesting was that any scripts tags in your vue components could reference the nonce from the window variable.

<template>
  <script :nonce="nonceValue">
    console.log('Safe inline script');
  </script>
</template>

<script setup>
const nonceValue = window. __CSP_NONCE__;
</script>

But that is assuming you have access to whatever is injecting the script.

Have you made sure the issue still exists when you run npm run build? All the vue stuff should be compiled by vite and it should put the nonce on the script for that....

vincent15000's avatar

vincent15000 liked a comment+100 XP

21h ago

choose hostinger for 2 years, it will save money. i used in fastvps for 2-3 years,, monthly 25 euro, same service i bought from hostinger 2 year only 125 usd and better & fastest

vincent15000's avatar

vincent15000 wrote a reply+100 XP

21h ago

Just to enhance security.

vincent15000's avatar

vincent15000 liked a comment+100 XP

21h ago

@vincent15000 Why have you added that prefix?

vincent15000's avatar

vincent15000 was awarded Best Answer+1000 XP

1d ago

Hello,

Here is my .env file.

REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret

REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_REVERB_APP_KEY=${REVERB_APP_KEY}
VITE_REVERB_HOST=${REVERB_HOST}
VITE_REVERB_PORT=${REVERB_PORT}
VITE_REVERB_SCHEME=${REVERB_SCHEME}

And here my app.js file.

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

And it works fine.

Just follow the Laravel documentation.

https://laravel.com/docs/13.x/broadcasting#client-reverb

vincent15000's avatar

vincent15000 wrote a reply+100 XP

1d ago

Hello,

Here is my .env file.

REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret

REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_REVERB_APP_KEY=${REVERB_APP_KEY}
VITE_REVERB_HOST=${REVERB_HOST}
VITE_REVERB_PORT=${REVERB_PORT}
VITE_REVERB_SCHEME=${REVERB_SCHEME}

And here my app.js file.

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

And it works fine.

Just follow the Laravel documentation.

https://laravel.com/docs/13.x/broadcasting#client-reverb

vincent15000's avatar

vincent15000 liked a comment+100 XP

1d ago

vincent15000's avatar

vincent15000 wrote a reply+100 XP

2d ago

@jsanwo64 @aleahy

I still get an error, probably the script concerned by this error doesn't have any nonce.

How can I be sure that all needed scripts, also the scripts that are dynamically injected by Vue, have a nonce ?

vincent15000's avatar

vincent15000 wrote a reply+100 XP

2d ago

Oh thank you I didn't even know that it was specified in the Laravel docs.

I have added the nonce like mentioned in the documentation, but I get this error.

Executing inline script violates the following Content Security Policy directive 'script-src 'self' 'nonce-3E6viSgDnRw26VLveosL5pgWUz8UlQRzLZRPS736''. Either the 'unsafe-inline' keyword, a hash ('sha256-uZu30YR5Q7xMFJcsmo+SoZwQUlCrvcfNNMjBIlUPasE='), or a nonce ('nonce-...') is required to enable inline execution. The action has been blocked.

Any idea what I can do now ?

vincent15000's avatar

vincent15000 liked a comment+100 XP

2d ago

Middleware (nonce generation)

public function handle(Request $request, Closure $next): Response
{
    $nonce = base64_encode(random_bytes(16));

    app()->instance('csp_nonce', $nonce);

    $response = $next($request);

    $csp = implode('; ', [
        "default-src 'self'",
        "img-src 'self' data:",
        "script-src 'self' 'nonce-$nonce'",
        "style-src 'self' 'nonce-$nonce' https://fonts.googleapis.com",
        "font-src 'self' https://fonts.gstatic.com",
    ]);

    $response->headers->set('Content-Security-Policy', $csp);

    return $response;
}

Pass nonce to Blade (Inertia root template) In your app.blade.php (or root layout):

@php($nonce = app('csp_nonce'))

Then:

<script nonce="{{ $nonce }}">
    window.__CSP_NONCE__ = "{{ $nonce }}";
</script>
vincent15000's avatar

vincent15000 liked a comment+100 XP

2d ago

In addition to what you've done, you need to tell Vite to add the nonce in the middleware via Vite::useCspNonce().

This is from the laravel docs:

        Vite::useCspNonce();
 
        return $next($request)->withHeaders([
            'Content-Security-Policy' => "script-src 'nonce-".Vite::cspNonce()."'",
        ]);

For convenience, it's also worth using Spatie's package: https://github.com/spatie/laravel-csp

vincent15000's avatar

vincent15000 started a new conversation+100 XP

3d ago

Hello,

How is it possible to add CPS headers with InertiaJS ?

I have tried this via a middleware.

public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);

    $csp = implode('; ', [
        "default-src 'self'",
        "img-src 'self' data:",
        "script-src 'self' 'unsafe-inline'",
        "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/css2",
        "font-src 'self' https://fonts.gstatic.com/s/figtree/v9/",
    ]);

    if (config('app.env') !== 'local') {
        $response->headers->set('Content-Security-Policy', $csp);
    }

    return $response;
}

But unsafe-inline is not secure.

I wanted to try with a nonce, but it seems to be quite complex to do that with InertiaJS.

Any suggestion ?

Thanks for your help.

V

vincent15000's avatar

vincent15000 wrote a reply+100 XP

3d ago

Ok just found, the /* updated */ part is the user input, then waiting for confirmation by the backend.

vincent15000's avatar

vincent15000 wrote a reply+100 XP

3d ago

I don't understand how this works.

form.optimistic((props) => ({ category: props.category, name: form.name })).put(route('admin.categories.update', { category: props.category }));

Can you explain me please ?

form.optimistic((props) => ({
  contacts: /* updated */
})).post(url);

The ```/* updated */ part is the confirmation from the backend with updated datas ? Or is it the frontend changes done by the user ?

vincent15000's avatar

vincent15000 liked a comment+100 XP

3d ago

Hey Vincent,

You're missing a return statement in your controller. Inertia requires a redirect after a mutation (POST/PUT/PATCH/DELETE) so it can fetch the fresh page props under the hood.

public function update(Request $request, Category $category)
{
    $category->fill($request->all());
    $category->save();

    return back(); // <-- You need this
}
vincent15000's avatar

vincent15000 wrote a reply+100 XP

3d ago

I have tested and it's ok, but there is a problem.

When a user navigates to another page, the authentication is lost.

vincent15000's avatar

vincent15000 liked a comment+100 XP

3d ago

check your page source which data google can get check and develop it. Google never get frontend data. somedays ago i developed a next js application which page data showing fine in frontend and pagesource failed to show these data. finally i solve it,,page source and understand the technical seo issue from: Screaming Frog SEO Spider: https://prnt.sc/qQFnPfXgOYRp

vincent15000's avatar

vincent15000 wrote a reply+100 XP

3d ago

Hello,

I know that __Host- is only with an HTTPS connexion.

But this can be interesting => The __Host- spec requires the domain attribute to be completely omitted, not just null.

I set it to null as suggested in some documentation, but it didn't work.

vincent15000's avatar

vincent15000 liked a comment+100 XP

3d ago

99% of the time I see this break, it's because you are testing locally over HTTP.

The __Host- prefix tells the browser to strictly enforce HTTPS. If you're using php artisan serve or an un-secured Valet/Herd site, the browser will silently drop the cookie. Inertia then fails to authenticate because the session cookie literally doesn't exist in your browser, causing 419 or 401 errors.

'cookie' => env('APP_ENV') === 'production' 
    ? '__Host-' . Str::slug(env('APP_NAME', 'laravel'), '_') . '_session'
    : Str::slug(env('APP_NAME', 'laravel'), '_') . '_session', 

Also, triple-check your .env file. If you have SESSION_DOMAIN=localhost (or anything else), remove it entirely. The __Host- spec requires the domain attribute to be completely omitted, not just null.

vincent15000's avatar

vincent15000 started a new conversation+100 XP

3d ago

Hello,

Laravel / InertiaJS / VueJS

I have added a prefix to the session cookie and it's not possible to login anymore.

'cookie' => env(
    'SESSION_COOKIE',
    '__Host-'.Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),

Why ?

Can you help me to keep this prefix ? What do you suggest me to check ?

Thanks.

V

vincent15000's avatar

vincent15000 started a new conversation+100 XP

4d ago

Hello,

I'm trying to use the optimistic updates with InertiaJS v3.

https://inertiajs.com/docs/v3/the-basics/optimistic-updates#form-helper

const save = async () => {
    form.optimistic((props) => ({ category: props.category, name: form.name })).put(route('admin.categories.update', { category: props.category }));

    editMode.value = false;
    updated.value = true;
};

The updated name is displayed on the screen, but its because the page is reloaded.

But I don't want any reload.

public function update(Request $request, Category $category)
{
    $category->fill($request->all());

    $category->save();
}

Hmmm ... can someboby explain how I can use the optimistic updates properly ?

Thanks for your help.

V

vincent15000's avatar

vincent15000 wrote a reply+100 XP

4d ago

In France, I recommend IONOS, I work with this company for several years and there is really no problem. They are also in the USA with specific offers.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

hi i am looking for vps server located in usa to host data of my website which is on heavy cms such as ghost . i asked from chatgpt and it says that ghost and other cms can only install on vps so i need to buy this. for this i browse for this and found that hostinger provides best vps plan wiht mulltiple ram version. with 2 gb to 16 gb with good price. now i want to confirm is it ok or is ther any other hosting provider https://shorturl.at/r0AlY whcih will be good. tell me your real feedback so i can decide before i buy one.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

There is Digital Ocean, Hetzner and even Laravel forge which now supports other aspects than just Laravel.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

its only a good price for 12 months

vincent15000's avatar

vincent15000 wrote a reply+100 XP

4d ago

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

Please add watched filter in "All series" section data is actively there and it will improve UX so much

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

They were on some kind of drive to turn Laravel PHP stuff into JS it felt like at one point, especially with Pest and Volt.. both of which, IMO, are a royal PITA and a mess to work with.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

A clumsy and awkward approach of recreating conventional OOP logic in functional style?

vincent15000's avatar

vincent15000 wrote a reply+100 XP

4d ago

Inertia SSR cannot be good or bad with SEO.

I just finished an application with its first functionalities with Laravel / InertiaJS / VueJS and SEO is very good.

SEO depends on several factors. You should check which one is responsible for a bad SEO.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

What are the SEO results that you're referring to? Traffic to the website?

Two months is a very short time. If it's a brand new site, Google may offer it as a search result to its users. If the results are not relevant to users, your ranking will start to drop.

The technology of the site shouldn't matter as long as:

  1. The content on your site is relevant to users.
  2. The content is well structured and semantically correct.
  3. The site is crawlable: every page has an address, you don't use path hacks (like #/my-route), and you use proper links with hrefs instead of JS navigation.
  4. The site isn't super slow.

Note that speed isn't the most important factor from a SEO standpoint, nor is it a sliding scale where a 10% faster page is ranked higher than others. Google just uses speed to classify sites, like fast/medium/slow.

SSR or MPA sites are not inherently better than SPAs. Google is aware of how SPAs work and they take that into account. They cache assets and crawl pages in two steps: before and after JS has done loading.

There's a lot of old SEO misinformation floating about. If you want real information, check what Google has to say. I suggest the YouTube channel Google Search Central as a starting point.

SEO consultants I would avoid.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

I’d check if your SSR actually returns full HTML in the page source, not just what shows with JS off. Also make sure each route sets proper meta tags and unique titles.

vincent15000's avatar

vincent15000 liked a comment+100 XP

4d ago

First test your website via Lighthouse and see which results you get from that. I have no issues with SEO and Inertia SSR.

vincent15000's avatar

vincent15000 liked a comment+100 XP

5d ago

This Youtube video presents exactly what you need: https://www.youtube.com/watch?v=lPX-BCkkoO0

vincent15000's avatar

vincent15000 wrote a reply+100 XP

5d ago

Policies is great to keep all authorizations at the same place.

A service is to handle business logic, you shouldn't write any authorization code in a service.

For example, in my code :

  • the services only execute the code for the business logic : get, store, update, delete, ...

  • the policies contain the authorizations

  • the controllers check for authorizations via the policies and then execute an action via the services

vincent15000's avatar

vincent15000 liked a comment+100 XP

5d ago

Thank you for the review, I appreciate it.

Initially I was only checking if the user had any role with the required permission in the PermissionService. Then I also wanted to identify which role the user is acting as, since it might change some actions, like different delete types or maybe save it in logs in the future. So that's why I though maybe I should also send the roleId from UI.

I'll look at the docs and links you shared to understand this better. I didn't use Policies before too, only did authorization in services, and used middleware for authentication. Thanks again!

vincent15000's avatar

vincent15000 liked a comment+100 XP

5d ago

When user goes to their roles page and go to a specific role panel, I will put the hidden roleId on forms, so I can check in authorization, if this user have this role, and if this role has the permission needed for the action. How is it? Is it a bad practice?

I agree with @jussimannisto do not use hidden fields. I suggest view some video series here on authentication and authorization. And review the documentation.

These checks are best done server side.

I also suggest taking this training: https://laracasts.com/series/laravel-from-scratch-2026

Also I gave an idea here: https://laracasts.com/discuss/channels/general-discussion/how-should-i-structure-authorization-for-owner-super-admin-community-admin-and-dynamic-roles-in-a-laravel-social-network?page=1&replyId=975679

Having same controller but a separate method for user verses admin.

vincent15000's avatar

vincent15000 wrote a reply+100 XP

6d ago

My opinion :

  • it depends on what you need, but it's not a bad pratice to have one controller for the superadmin and one controller for the users

  • the same logic can be applied to views and routes

  • to check if a user has the permission to do an action, it's not a good practice at all to only check the role id in the frontend, you have to check authorizations in the backend and the best way to do that is to write policies, inside policies you can check the roles and/or the permissions

What you name authority is a role.

In pratice a user can have one or several roles and each roles comes with some permissions. It's generally not recommended to assign permissions directly to users. The best way is to assign permissions to roles and to assign roles to users. But for fine permissions control, you can occasionally assign permissions to users if it's really needed in your application, I don't do so, but sure some cases can justify to do so.

If you need help to do all this, you can have a look at this Laracasts series.

https://laracasts.com/series/mastering-permissions-in-laravel

vincent15000's avatar

vincent15000 liked a comment+100 XP

6d ago

I have 5 types of authority:

super admin (highest), dynamic roles created by super admin, community owner, dynamic roles created by community owner, normal users,

I have separate community controller, blade views and routes for super admin and user. And I might do one more for dynamic roles. I will check the authentication from the routes with middleware. Is it okay to do these?

Users can have different roles. And if they delete their things as a user it will get soft delete, while as other role it will get status = deleted. So I have to know, as what role they are requesting this action.

When user goes to their roles page and go to a specific role panel, I will put the hidden roleId on forms, so I can check in authorization, if this user have this role, and if this role has the permission needed for the action. How is it? Is it a bad practice?

I would appreciate your guidance, this is my first time working with auth systems, so I don't know what I do might be bad practice. The project is final course project.

vincent15000's avatar

vincent15000 liked a comment+100 XP

6d ago

What kind of attack are you talking about?

Users can do anything with their own front end, so they can of course submit the form anywhere. That's why you validate and authorize everything server-side.

On the front end, what you need to worry about is code injection that could affect other users (XSS).

vincent15000's avatar

vincent15000 wrote a reply+100 XP

6d ago

@martinbean

Sorry I thought it was logical because of the multipart title of the post here.

With multipart/form-data, I send a file from a VueJS form to the backend.

Works means that the file is sent and received by the backend, doesn't work means that the file isn't sent and is not received by the backend.

vincent15000's avatar

vincent15000 liked a comment+100 XP

6d ago

@vincent15000 What do you mean by “works” and “doesn’t work”?

We have no idea what data you’re sending, to where, what you expect to see, nor what you’re actually seeing.

vincent15000's avatar

vincent15000 liked a comment+100 XP

1w ago

@randy_johnson Pest is based on PHPUnit. Just take a look at the tests directory in the laravel/laravel repository for the skeleton files you need to go back to using PHPUnit.

vincent15000's avatar

vincent15000 liked a comment+100 XP

1w ago

lol. FOR SURE! that deserved font size 50, at least :P

vincent15000's avatar

vincent15000 wrote a reply+100 XP

1w ago

I've already done this in the past too.

Rather than upgrading, it's sometimes faster to create a new application.

Here is what I did :

  • backup all data
  • keep all views and actions
  • create a new application
  • implement all functionalities, one by one
vincent15000's avatar

vincent15000 liked a comment+100 XP

1w ago

Also before doing anything and while converting at various times:

Backup your data

vincent15000's avatar

vincent15000 liked a comment+100 XP

1w ago

@iamyannc Hey. I’ve done a lot of these type of re-factoring and re-platforming projects in the past. The way I’d approach it would be like this:

  • Get the application running on a newer version of PHP. So upgrade to 7, fix any usage of deprecated APIs and libraries, and then when possible upgrade to PHP 8 and do the same.
  • Once you’ve got the vanilla PHP application running on a modern version of PHP, create a new Laravel application and dump your legacy application’s file in the public directory.
    • Rename Laravel’s index.php file to something like laravel-index.php to avoid clashing with your legacy index.php file.
    • Tweak your .htaccess or nginx config to just load a file if it exists, or fall back to Laravel’s front controller.
  • You should now have a Laravel application, but with no requests actually being routed through it to start off with, and instead requests hitting your legacy application as before.
  • Slowly start re-factoring your legacy application to Laravel controllers, views, etc. Do this slowly, and one discreet part at a time. Trying to re-factor too much in one go just leads to lots of files being touched, none of them 100% converted, and the dreaded feeling of, “Urgh, I need to git reset this and start over.”
  • As you do the above, the number of files from the legacy application will decrease, and the number of Laravel files increase, until you’re left with nothing of the legacy application.

Happy for you to reach out if you have any questions. DM me on Twitter 𝕏 (https://x.com/martinbean) and I can share my email address.