Skip to content
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

Live queries with axios interceptor don't work #278

Open
mihaa1 opened this issue Oct 26, 2023 · 7 comments
Open

Live queries with axios interceptor don't work #278

mihaa1 opened this issue Oct 26, 2023 · 7 comments

Comments

@mihaa1
Copy link

mihaa1 commented Oct 26, 2023

When using live queries + axios interceptor to inject jwt - request api/stream doesn't get it.

  1. Setup remult project live queries + jwt + axios interceptor as in this tutorial:
  2. jwt is not added to Authorization header in requests api/stream

Expected behavior
interceptor catches these requests as well to authenticate in server

Desktop (please complete the following information):

  • OS: macos
  • Browser chrome
@noam-honig
Copy link
Collaborator

Hi @mihaa1,

The default implementation for the SubscriptionClient used in this tutorial, uses the browser's EventSource object that doesn't support adding header elements

But don't worry, you don't need it - because registering the the api/stream still doesn't mean that you'll get any messages.

To get a message, the live query subscribes to a channel, using the normal http call, in your case axios, and will have the authorization header - so there is no data leak risk here.

Alternatively, you can implement an alternative implementation of the SubscriptionClient that uses fetch, here's a popular fetch client:
https://www.npmjs.com/package/@microsoft/fetch-event-source

You can create an adapter for it, the entire adapter for the EventSource is only 100 lines of code, so creating an adapter should be easy enough.
Here's the code for the EventSource Adapter.
https://www.npmjs.com/package/@microsoft/fetch-event-source

All that said - I stand by the first option where you don't need the jwt for the stream, as registering to the stream doesn't give you any message

Let me know if that works

@alexchern
Copy link

Hi,

I have the same problem.
I tried to add '/api/stream' to the list of ignored paths in ExpressJWT, but to make it work, I practically have to ignore everything...

app.use(
    expressjwt({
        secret: globalData.ACCESS_TOKEN,
        credentialsRequired: false,
        algorithms: ['HS256'],
        onExpired: async (req: JWTRequest, err) => {
            throw err;
        },
    }).unless({
        path: [
            '/',
            '/api/login',
            '/api/logout',
            '/api/signup',
            '/api/stream',
            '/api/subscribe',
            '/api/unsubsribe',
            '/api/stream/subscribe',
            '/api/stream/unsubscribe',
            '/api/_liveQueryKeepAlive',
       .... other paths.
        ],
    })
); 

I tried to follow the tutorial, but it appears that the code is no longer applicable to the current version, as there is no 'remult.setUser()' function, etc.

Thanks,

Alex

@noam-honig
Copy link
Collaborator

Hi,
I recommend that you try the newer tutorial (remult is way more fun in newer versions):
https://remult.dev/tutorials/react/
Here's the video version:
https://youtu.be/VN27pdF3a6c?si=K-Wii_2A7Lz8dmdX

These tutorials no longer use axios and JWT - instead, they use 'cookie-session'

If you do want to have JWT - here's an example of how I got it to work without the exclude paths...
https://github.com/noam-honig/jwt-header-example

Here's the specific commit:
noam-honig/jwt-header-example@b5a35d6

Let me know if that helps

@alexchern
Copy link

Thanks. Will try to understand how it works... I just moved to axios in order to be able to set the authorization... In your example the "fetch" is used...

Alex

@noam-honig
Copy link
Collaborator

@alexchern you don't really need axios for that - but if you want to use axios, you can do the same with the intercepters there.

Let me know how it worked or if you need more help

@impleotv
Copy link

Thanks a lot.
I replaced axios with fetch, did something similar to your example and it seems to work. The last thing I need to understand is how to catch the 403 error (in liveQuery or elsewhere) when the token is invalid or expired. I need this in order to send the customer back to the login page. I would need to catch the disconnect error as well, when the server goes offline.
How to properly do this with Remult?

Once again, thanks for your support,

Alex

@noam-honig
Copy link
Collaborator

Hi @impleotv ,

The quick solution would be to handle the response back from fetch - and based on it simply redirect to the login page:
window.location.href = 'https://www.example.com/signIn';

Or - you can move the code that set's the httpClient, into the component and tell it to do some react thing (navigate) when there is an error

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

No branches or pull requests

4 participants