vincent15000 wrote a reply+100 XP
4h ago
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 wrote a reply+100 XP
4h ago
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 liked a comment+100 XP
21h ago
vincent15000 wrote a reply+100 XP
21h ago
vincent15000 liked a comment+100 XP
21h ago
@vincent15000 Why have you added that prefix?
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.
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.
vincent15000 liked a comment+100 XP
1d ago
import 'bootstrap';
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Pusher from 'pusher-js';
import 'bootstrap';
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Pusher from 'pusher-js';
const BASE = 'http://localhost/ecart/prd';
const CSRF = document.querySelector('meta[name="csrf-token"]')?.content || window.App?.csrfToken;
console.log('🔥 CSRF USED:', CSRF);
window.pusher = new Pusher(import.meta.env.VITE_REVERB_APP_KEY, {
wsHost: window.location.hostname,
wsPort: 8080,
wssPort: 8080,
forceTLS: false,
enabledTransports: ['ws'],
cluster: 'mt1',
disableStats: true,
authEndpoint: '/broadcasting/auth',
auth: {
headers: {
'X-CSRF-TOKEN': CSRF,
'X-Requested-With': 'XMLHttpRequest'
}
},
withCredentials: true
});
``` i a m using xamp server getting below error
chat.js:203 ❌ [Chat] Subscription error for private-chat.chat_test_1777144082 {type: 'AuthError', error: 'Unable to retrieve auth string from channel-author…r.com/docs/channels/server_api/authorizing-users/', status: 403}
vincent15000 wrote a reply+100 XP
2d ago
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 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 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 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 wrote a reply+100 XP
3d ago
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 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 wrote a reply+100 XP
3d ago
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 wrote a reply+100 XP
3d ago
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 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 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 wrote a reply+100 XP
4d ago
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 liked a comment+100 XP
4d ago
vincent15000 liked a comment+100 XP
4d ago
vincent15000 wrote a reply+100 XP
4d ago
vincent15000 liked a comment+100 XP
4d ago
vincent15000 liked a comment+100 XP
4d ago
vincent15000 liked a comment+100 XP
4d ago
vincent15000 wrote a reply+100 XP
4d ago
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:
- The content on your site is relevant to users.
- The content is well structured and semantically correct.
- 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.
- 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 liked a comment+100 XP
4d ago
vincent15000 liked a comment+100 XP
4d ago
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 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 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 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 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 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 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 wrote a reply+100 XP
6d ago
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 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 liked a comment+100 XP
1w ago
vincent15000 wrote a reply+100 XP
1w ago
vincent15000 liked a comment+100 XP
1w ago
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 resetthis 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.