Skip to content

Add authorization headers #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 12, 2024
Merged

Add authorization headers #32

merged 2 commits into from
Nov 12, 2024

Conversation

michaelaguiar
Copy link
Contributor

@michaelaguiar michaelaguiar commented Nov 11, 2024

Before, if you included the following authorization headers to the Echo connection block, it would be ignored and private channels would fail to connect:

auth: { headers: { Authorization: "Bearer {TOKEN}", }, }

This PR makes it so if you included auth.headers.Authorization or the shorter bearerToken options, it will now add it to the authentication headers.

I also converted the axios call to use vanilla js fetch to remove the need for a third party library. axios was removed as a dependency.

Copy link

codecov bot commented Nov 11, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 38.23%. Comparing base (e7ca7c8) to head (99adec3).
Report is 3 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master      #32      +/-   ##
============================================
- Coverage     43.07%   38.23%   -4.84%     
  Complexity       61       61              
============================================
  Files             9        6       -3     
  Lines           397      272     -125     
  Branches         14        0      -14     
============================================
- Hits            171      104      -67     
+ Misses          218      168      -50     
+ Partials          8        0       -8     
Flag Coverage Δ
jest ?
pest-8.1 38.23% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@leob
Copy link
Collaborator

leob commented Nov 12, 2024

@michaelaguiar Thanks for this, however I'm not sure what we're fixing here - from what I've seen auth works fine for us, also for private channels ... is this PR related to an existing issue? I've looked through the issue list:

https://github.com/georgeboot/laravel-echo-api-gateway/issues)

but I didn't see anything ... I'm a bit reluctant to merge this if I'm not sure what issue we're fixing here.

Second remark - I wonder if we really should be removing Axios - please see this issue and the conclusion we came to:

#30

Is the removal of Axios necessary for the auth headers fix to work?

@michaelaguiar
Copy link
Contributor Author

Good point! If Echo relies on it, we should keep axios. It’s absolutely not necessary for the auth header fix. I will revert the axios removal.

In my use case, the client needs to authenticate with a separate api server that uses passport via a bearer token. I realized that adding the auth.headers.Authorization option wasn’t actually adding the authorization header at all to the /broadcasting/auth request. You can verify this by adding that option, and reviewing the request in the network tab of the browser console. Please correct me if I’m wrong!

After I roll back the axios removal, the only change is adding the headers to the axios auth request for private / presence. You should also see that no headers are being added currently, regardless of the defined options.

I’ll revert axios in just a few minutes and you can take a look. Feel free to take your time and verify yourself!

@leob
Copy link
Collaborator

leob commented Nov 12, 2024

@michaelaguiar Okay thanks ... will wait for the final version!

@georgeboot
Copy link
Owner

Understand the use case and would be good to support this

@michaelaguiar
Copy link
Contributor Author

Ok Axios is back in. The authorization header is minor, but helps when the client needs to authenticate to a separate remote server that requires a Bearer Token.

For example:

  window.Echo = new Echo({
    broadcaster,
    host: "wss://" + API_ID + ".execute-api.us-west-2.amazonaws.com/" + STAGE,
    authEndpoint: AUTH_URL + "/broadcasting/auth",
    bearerToken: getCookie("session_token"),
    enabledTransports: ["ws", "wss"],
  });

bearerToken is just shorthand for the auth.headers.Authorization block, and is used for the native connectors like pusher / socket.io. The native connector that converts bearerToken to auth.headers.Authorization / userAuthentication.headers.Authorization is never run on our connector, so it's added here to keep the same pattern.

For reference: laravel/echo#353

Let me know what you guys think!

@leob
Copy link
Collaborator

leob commented Nov 12, 2024

@michaelaguiar @georgeboot Okay, now I finally understand what's the point :)

Yes, authentication to set up "private" channels was something we also definitely needed in our own app ... the way we worked around it (we use Axios in our app) was like this, with window.axios.defaults.headers.common['Authorization']:

// Needed for auth call in function "actuallySubscribe" of laravel-echo-api-gateway
// (node_modules/laravel-echo-api-gateway/dist/laravel-echo-api-gateway.js)

window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;

window.Echo = new Echo({
  authEndpoint: import.meta.env.VITE_APP_BACKEND_URL + '/api/broadcasting/auth',
  broadcaster,
  host,
});

and this works, but of course what you've now implemented now is much more elegant - and consistent with "the Echo standard" (as per laravel/echo#353).

I think we won't even need to change our application code after upgrading, but if we want to we could get rid of our "hack" ...

Happy to merge this - but shall we add your little example snippet to the README, so that people know how to use it? So I mean this:

 window.Echo = new Echo({
    broadcaster,
    host: "wss://" + API_ID + ".execute-api.us-west-2.amazonaws.com/" + STAGE,
    authEndpoint: AUTH_URL + "/broadcasting/auth",
    bearerToken: getCookie("session_token"),
    enabledTransports: ["ws", "wss"],
  });

P.S. what we're doing in our own app in a local dev environment (when connecting to a local websockets server, not AWS) is this:

window.Echo = new Echo({
  auth: {
    headers: {
      Authorization: 'Bearer ' + token,
    }
  },
  broadcaster: 'pusher',
...........

I think this is the "old syntax" for Echo to pass the bearer token, back when the bearerToken option hadn't yet been introduced? Anyway, I think for now we'll just leave our application code as it is and just try to upgrade, and then it should just continue to work ...

@michaelaguiar
Copy link
Contributor Author

Exactly! I needed to add the headers directly to Axios just as you did, and figured there was a cleaner way to do it directly in the echo block.

Yea I found that bearerToken was added to simplify the block a bit, but it does exactly that - adds the auth.headers.Authorization if it's added. You can use either method and it should just work with my update.

Just updated the README. What do you think?

@leob leob merged commit 22ff8bb into georgeboot:master Nov 12, 2024
5 of 8 checks passed
@leob
Copy link
Collaborator

leob commented Nov 12, 2024

@michaelaguiar I think it's looking great ... I've merged it!

I didn't publish a new version to npm yet, but will probably do so tomorrow (there'a another PR in the making which I might want to include, but I need to check that one a little bit more thoroughly) ...

Thanks!

P.S. ah haha, it's now complaining about Property 'bearerToken' does not exist on type 'Options' in Websocket.ts:

https://github.com/georgeboot/laravel-echo-api-gateway/actions/runs/11803244330/job/32880778514

Never mind, we'll fix that in another PR ... but, what we should maybe do is configure our Github Actions to run not just on commits to master but also on pull requests:

https://futurestud.io/tutorials/github-actions-run-on-pull-request

@michaelaguiar
Copy link
Contributor Author

I agree! I can take a look and get that updated a little later.

@leob
Copy link
Collaborator

leob commented Nov 14, 2024

@michaelaguiar I've merged it but I'm now struggling with producing a release - publishing to npmjs just refused to work ... by the way I combined this PR (32) with another PR (31) in the same release (0.5.1 originally but I messed around a bit and now it's 0.5.2, lol) ... haven't succeeded in producing/publishing a release though :)

@michaelaguiar
Copy link
Contributor Author

What errors are you getting? Anything I can do to help?

@leob
Copy link
Collaborator

leob commented Nov 15, 2024

What errors are you getting? Anything I can do to help?

@michaelaguiar See the discussion (comments) at the bottom of the other PR:

#31

but basically the Github Action logs says this:

Run yarn publish --access public --tag latest
........................
error Couldn't publish package: "registry.npmjs.org/laravel-echo-api-gateway: Not found"

And that's it, more or less ...

There isn't any other useful info regarding what the problem is, and a quick google search yields nothing, I'm coming up empty ... basically stuck at this moment as the yarn command seems to "refuse" to publish to npmjs !

I'm almost out of ideas - what we still could do is:

  • pass the --verbose flag to the yarn command, maybe it shows something which provides a hint

  • or maybe we can just dump yarn and switch to npm- I mean, does yarn now (in 2024) still have any advantages over npm ... ?

P.S. by the way: the "test" action that precedes the "publish" action also has failures - the Jest run fails, as well as another job - but I don't believe that that should directly influence the "publish" action ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants