cdr95985

cdr95985

Member Since 1 Year Ago

Experience Points 660
Experience Level 1

4,340 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 4
Lessons
Completed
Best Reply Awards 0
Best Reply
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • Chatty Cathy Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

30 Jan
1 year ago

cdr95985 left a reply on Authorizing Private Event Channels (not Triggering WebSocket Server Listener). Public Events Work! - Laravel 5.5

@tiagomatosweb when I posted this question, I was using my own Socket.io implementation. I have since moved on to use the laravel-echo-server (community server), specifically to address the channel authentication problem.

From what I read in the source code of laravel echo (included in laravel js dependencies)--which I will refer to as Echo from here on out--and the laravel-echo-server... it appears that when Echo is instantiated on the client side, and if you are "subscribing" it to a channel that needs to be authenticated as defined in the laravel docs ( i.e. Echo.private() .notify()... NOT .public() ), Echo will try to hit an authentication route which is based on how you configure Echo in /resources/assets/js/app.js or bootstrap.js.

Since I was using my own socket.io implementation, it did not hit the auth url on the socket.io server I had (because it didn't exist) so it never authenticated the user. I think it is by design that Echo will return "true" and allow a user to listen to a private or notify channe if the auth url returns a 404... again, the code that triggers the auth in Echo is under the hood. You can find it yourself on within if youre curious.

The laravel echo server a actually has an endpoint for authenticating private / notify channels. It accepts a csrf token and some more details need to auth a user from Echo, builds a request, and sends it to the auth route in the laravel php application (which is a default route provided from laravel 's broadcast auth routes I think). The echo server will then respond with the laravel app's indication of whether or not a user is authorized based on what it was sent.

So, tl;dr: implement a laravel echo server.

Oh, to save you another headache.. If you are developing on the same server you will be hosting your production environment on, prefix your channels that you broadcast on with the app's environment. You will also need to prefix the channels on the client side with the same variable. I did this by passing the environment down when rendering the layout file in blade.

Laravel echo server does not support multiple instances out of the box. That is how I get around that implementation. So you will likely have one redis server and one laravel echo server on your stack.

Let me know if you have other issues. Thanks =)

07 Nov
1 year ago

cdr95985 started a new conversation Laravel Echo Does Not POST To /broadcasting/auth On Page Load

I am using Laravel 5.5. When landing on a page that includes the Laravel app.js compiled typescript with Laravel Echo instantiated, as well as Echo listening to a private channel, I noticed that the /broadcasting/auth endpoint is not being called.

Does anyone have any idea why this is?

06 Nov
1 year ago

cdr95985 started a new conversation Private Channel And Events Work But Do Not Get Ran Through Authorization Service Provider?

I have events broadcasting over the public, private, and presence channels, however, the private and presence events are NOT getting authorized. Even though they are NOT getting authorized, users subscribed to the private and presence channels are able to get the messages as they are emitted.

I am using Laravel 5.5 with a custom socket.io websocket server with Redis. Again, all 3 event types are broadcasting to all clients appropriately.

Below is the relevant code.

TestController.php

    public function firePrivateEvent()
    {
        $data = [
            'username' => 'Private JohnDoe'
        ];
        
        broadcast(new \App\Events\PrivateEvent($data));
        return "TRUE";
    }

PrivateEvent.php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Support\Facades\Log;

class PrivateEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $data;
            
    /**
     * Create a new event instance.
     *
     * Data passed in will be serialized, along with any public properties
     * 
     * @return void
     */
    public function __construct($data)
    {
        //
        $this->data = $data;
        
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        //return new PrivateChannel('test-channel');
        Log::Info("[Event Raised]: PrivateEvent on private-channel");
        return new PrivateChannel('private-channel');
    }
}

BroadcastServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;

class BroadcastServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Broadcast::routes();

        require base_path('routes/channels.php');
    }
}

Channels.php

Broadcast::channel('private-channel', function($user) {
    Log::Info("Authorizing private-channel event"); // this is never logged!
    return true;
});

Socket.io server: app.js

redis.subscribe('private-private-channel'); // I've instantiated PrivateChannel with a channel name of 'private-channel', therefore the channel I want to subcribe to is 'private-private-channel', since that class prepends 'private-' to the value passed in.

redis.on('message', function(channel, message){
   
    message = JSON.parse(message);
    console.log('-------------------')
    console.log("MSG FIRED");
    console.log('message channel: ' + channel);
    console.log('message event: ' + message.event);
    console.log(message);
    console.log('emit to: ' + channel + ':' + message.event);
    io.emit(message.event, channel, message.data);
    console.log('-------------------')
});

Client side JS. The CRSF Token, compiled app.js typescript, and the socket.io library are included in the page as well.

            var pr = Echo.private('private-channel')
            .listen('PrivateEvent', (e) => {
                console.log("[GOT PRIVATE EVENT]:");
                console.log(e);
                this.users.push(e);
            });

Please let me know if you have any suggestions. Thank you!

03 Nov
1 year ago

cdr95985 left a reply on Authorizing Private Event Channels (not Triggering WebSocket Server Listener). Public Events Work! - Laravel 5.5

*** Channel Authorization Problem ***

While this is all wonderful, it appears that my broadcasting routes / channels are NOT being checked against the authorization method I defined in channels.php.

Broadcast::channel('private-private-channel', function($user) {
    Log::Info("Authorizing private-private-channel event");
    return 0;
});

Broadcast::channel('private-channel', function($user) {
    Log::Info("Authorizing private-channel event");
    return 0;
});

I would assume I would HAVE to manually define the private channels with the "private-" prefix. Either way, neither log messages are being fired. Any advice as to how and why?

Note: The Echo.private() channel subscription has the following options under auth:

authEndpoint: "/broadcasting/auth"
broadcaster: "socket.io"
csrfToken: null
host: "https://mydomain.com:3031"
hostname: "dev.mydomain.com"

My concern is that Echo is trying to authorize to "dev.mydomain.com:3031/broadcasting/auth", but that is where the socket.io server is being hosted. I am assuming that Echo is smart enough to hit the Laravel App at the hostname, and not the host, but who knows? Any advice? Thanks!

cdr95985 left a reply on Authorizing Private Event Channels (not Triggering WebSocket Server Listener). Public Events Work! - Laravel 5.5

Update: I was able to get the private events to broadcast and to be picked up by the socket.io server, as well as emitting them to the client side.

It appears that, when using Laravel-Echo and subscribing to a private channel like so:

            var pr = Echo.private('private-channel')
             .listen('PrivateEvent', (e) => {
                 console.log("[GOT PRIVATE EVENT]:");
                 console.log(e);
             });

... will actually APPEND A PREFIX to the channel name that we pass in. So, when I logged "pr" to the console, I found that the channel name that it was LISTENING to was 'private-private-channel'.

SocketIoPrivateChannel {events: {…}, name: "private-private-channel", socket: r, options: {…}, eventFormatter: EventFormatter}
eventFormatter
:
EventFormatter {namespace: "App.Events"}
.
.
.

I thought "hm, weird", so I wondered if Laravel itself did the same thing when it broadcasts on private channels using event(new App\Event\SomeEventThatBroadcastsOnPrivateChannel), where the broadcastOn() function looks like so:

    public function broadcastOn()
    {
        //return new PrivateChannel('test-channel');
        Log::Info("[Event Raised]: PrivateEvent on private-channel");
        return new PrivateChannel('private-channel');
    }

In the socket.io server, I subscribed to 'private-private-channel', and sure enough, the redis.on('message') event was fired, and my Echo client code picked up the emitted data (while I instantiated it with 'private-channel', it listened for 'private-private-channel')!

TL;DR

It appears that when defining an event to broadcast on a private channel, Laravel takes the $channelName that you pass in and APPENDS it with 'private-'.

On your socket.io server, you should subscribe to "private-$channelName".

On your client side javascript, using Echo, you should subscribe to a private channel like so: Echo.private($channelName).Listen(...).

*** Channel Authorization Problem *** While this is all wonderful, it appears that my broadcasting routes / channels are NOT being checked against the authorization method I defined in channels.php.

Broadcast::channel('private-private-channel', function($user) {
    Log::Info("Authorizing private-private-channel event");
    return 0;
});

Broadcast::channel('private-channel', function($user) {
    Log::Info("Authorizing private-channel event");
    return 0;
});

I would assume I would HAVE to manually define the private channels with the "private-" prefix. Either way, neither log messages are being fired. Any advice as to how and why?

Note: The Echo.private() channel subscription has the following options under auth:

authEndpoint: "/broadcasting/auth"
broadcaster: "socket.io"
csrfToken: null
host: "https://mydomain.com:3031"
hostname: "dev.mydomain.com"

My concern is that Echo is trying to authorize to "dev.mydomain.com:3031/broadcasting/auth", but that is where the socket.io server is being hosted. I am assuming that Echo is smart enough to hit the Laravel App at the hostname, and not the host, but who knows? Any advice? Thanks!

cdr95985 left a reply on Change Log Name In Laravel 5.5

@Talinon, That did it. Thank you so much for your time! I was unaware of the setfacl command--this could be very useful in the future. Thanks a lot!

31 Oct
1 year ago

cdr95985 started a new conversation Private Event Triggering WebSocket Server Listener

I have implemented a Socket.IO Server with my Laravel Application. I am able to broadcast and update the view to all connected clients using public events. However, when I try using private events, it seems that these are not triggering the listener on my socket.io server.

What is happening now from and end-user standpoint: When a user connects to the page, the web socket server log knows that a user connected. When firing the event (which occurs when the user hits the page), the event is logged in laravel.log. The event is sent to the queue and in Redis (I can see it in "queues:default" in the Redis db). The Queue Listener is running (manually) and then processes the private event (removing it from the Redis db). The web socket server never catches the broadcasted event over the "private-channel" at this point.

NOTE: The authorization route for "private-channel" NEVER fires off the log as defined!

I've verified that the channel name is spelled correctly in the web socket server, the event class, and the client page.

Below is the relevant code (I think).

TestController.php @ app.com/PrivateEvent ... public function firePrivateEvent() { $data = [ 'username' => 'Private JonDoe' ];

    // This is firing but not getting caught by socket.io
    event(new \App\Events\PrivateEvent($data));
    return view('test.redis');
}

...

PrivateEvent.php The log message in here is getting fired. ...

namespace App\Events;

use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Support\Facades\Log;

class PrivateEvent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels;

public $data;
        
/**
 * Create a new event instance.
 *
 * Data passed in will be serialized, along with any public properties
 * 
 * @return void
 */
public function __construct($data)
{
    //
    $this->data = $data;
    
}

/**
 * Get the channels the event should broadcast on.
 *
 * @return \Illuminate\Broadcasting\Channel|array
 */
public function broadcastOn()
{
    //return new PrivateChannel('test-channel');
    Log::Info("[Event Raised]: PrivateEvent on private-channel");
    return new PrivateChannel('private-channel');
}

} ...

channels.php This log message is never recorded. ... Broadcast::channel('private-channel', function($user) { Log::Info("Authorizing private-channel event"); return 0; }); ...

BroadcastingServiceProvider.php ... namespace App\Providers;

use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Broadcast;

class BroadcastServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Broadcast::routes();

    require base_path('routes/channels.php');
}

} ...

websocketserver.js The logs here are not getting fired when broadcasting across the private-channel, but they do when broadcasting across the public-channel. ... // subscribe to channels in which we want to notify clients on when updated redis.subscribe('public-channel'); redis.subscribe('private-channel');

redis.on('message', function(channel, message){ //console.log(channel, message);

message = JSON.parse(message);
console.log('-------------------')
console.log("MSG FIRED");
console.log('message channel: ' + channel);
console.log('message event: ' + message.event);
console.log(message);
console.log('emit to: ' + channel + ':' + message.event);

// io.emit(channel + ':' + message.event, message.data); //test-channel:UserSignedUp io.emit(message.event, channel, message.data); //test-channel:UserSignedUp console.log('-------------------') }); ...

client_view.blade.php Obviously we never get this far with the private-channel, but we do with the public-channel. This page has the CSRF token embedded, as well as the client side socket.io library and the compiled typescript "app.js" where Echo is defined in. ... new Vue({ el: '#users', data: { users: ["t1", "t2"] }, mounted: function(){ console.log("Vue is mounted!");

        Echo.channel('public-channel')
         .listen('PublicEvent', (e) => {
             console.log("[GOT PUBLIC EVENT]:");
             console.log(e);
             this.users.push(e);
         });
         
        Echo.private('private-channel')
         .listen('PrivateEvent', (e) => {
             console.log("[GOT PRIVATE EVENT]:");
             console.log(e);
             this.users.push(e);
         })
    }
});

...

I'm unsure of where to debug next. Can anyone help me? Thanks!

cdr95985 left a reply on Change Log Name In Laravel 5.5

@Talinon, This does bring me one step closer.

This solution fixes the issue with the end-user seeing the file permissions error if the log file was created when the php artisan command was run.

However, my user now receives the file permissions error when running artisan commands after the log was newly created by the end-user hitting the page. This is because the log file is created with read only permissions on the group id.

Only the OWNER of the file can write to the log. So we need to find a way to either ensure the group can write to the new file when it is created, or find another way to approach this (such as changing the log name, but that appears to be deprecated). Thanks for your time btw.

cdr95985 left a reply on Change Log Name In Laravel 5.5

I'm sorry. I should have clarified.

I have my logs set to "daily". When the log file is created on a new day, the file is created with the persmissions "644" or "-rw-r--r--". The owner and group the file belongs to is set to "www-data" (as expected). When hitting the page the log is recorded correctly.

The issue is this:

If the log file does not exist at the time that a "php artisan" commadn is run, for example, the "php artisan queue:work" or "listen" command, the log file is created with the permissions of the user running the command. Now, after the fact, if an end-user hits a page that writes to the log, the page breaks because it is trying to write to a log that exists but does not belong to www-data.

I hope that is clear. My question is this: how do I prevent this scenario?

cdr95985 started a new conversation Change Log Name In Laravel 5.5

Hello, how can we change the default log name in Laravel 5.5? I am having issues with logging when running the PHP Artisan Queue:Work and Listen command. The log file that is created is not able to be written to. The owner and group of the created file is www-data.

I saw a solution here: https://laracasts.com/discuss/channels/laravel/log-permission-problem

But that does not apply to Laravel 5.5. Thanks.