Skip to content
This repository has been archived by the owner on Oct 30, 2023. It is now read-only.

Auth.requestToken(): input must not start with a slash when using prefixUrl #8

Closed
mariesta opened this issue Mar 14, 2022 · 14 comments
Closed
Assignees

Comments

@mariesta
Copy link

mariesta commented Mar 14, 2022

Context

I have installed ably-labs/react-hooks in order to use the configureAbly() and useChannel hook in My Next.js app. I created an API endpoint for authentication:

import Ably from "ably/promises";

export default async function handler(req, res) {
    const client = new Ably.Realtime(process.env.ABLY_API_KEY);
    const tokenRequestData = await client.auth.createTokenRequest({ clientId: 'ably-blog-app' });
    res.status(200).json(tokenRequestData);
};

And called configureAbly in my component:

configureAbly({ authUrl: '/api/createTokenRequest' });

It works fine apart from the fact that I get log messages in my server:

Ably: Auth.requestToken(): token request signing call returned error; err = Error: `input` must not start with a slash when using `prefixUrl`

I have tried removing the slash (this causes an issue) and I have moved the configureAbly in various places (inside a component, in _app.js), but it still appears. There is a new one every 30 seconds. Any idea what might cause it?

@retsamboon
Copy link

I am seeing the same error and after doing some digging, I found that this is caused by a bug in the Ably dependency got v11.8.2 npm package. This bug seems to have been fixed by sindresorhus/got#1667 (released in Got 12).

@thisisjofrank
Copy link
Contributor

Hey Mariesta,
Thanks for flagging this, we've solved it by providing a specific value for the API root in the .env file then using it when you configure ably. You can see an example of that here: https://github.com/ably-labs/next-and-ably#configuration
You'll then have to specify the correct value in your Vercel environment variables when you deploy.

@starlight-akouri
Copy link

@thisisjofrank I don't think your solution solves this problem. I am also still struggling with the same exact symptoms as the OP, but my got version is "^11.8.5",. I am wondering if I should manually set this to ^12?

@oleg131
Copy link

oleg131 commented Jun 26, 2023

I am having the same issue. Currently, the only solution is to manually modify the authUrl to be absolute (which would be different e.g. in dev and prod)

@WillSmithTE
Copy link

Yeah this is annoying, @thisisjofrank should this really be closed?

@thisisjofrank
Copy link
Contributor

I'm afraid I no longer work on this product. Please email DevRel@ably.com to get some eyes on it.

@stmoreau stmoreau reopened this Aug 19, 2023
@sync-by-unito
Copy link

sync-by-unito bot commented Aug 19, 2023

➤ Automation for Jira commented:

The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3812

@stmoreau
Copy link
Contributor

We understand this issue may have been closed while the fix for it was not working. Apologies about that, I have now re-opened the issue and we will look into it in the next week.

@owenpearson
Copy link
Contributor

Hey all, thanks for raising this issue with us!

This error message actually comes from got which is the HTTP client used by Ably when used in NodeJS. The error message itself is caused by got not being able to make an HTTP request to a URL which starts with a / (which makes sense really, in NodeJS there's no window.location or anything, so there's no obvious way to resolve a path without an explicit host name or scheme).

The real problem if you're seeing this issue, is that your NextJS application is creating an Ably client on the server side (ie in a NodeJS process) but really the Ably client should only be created on the client side. In my experience, the best way to ensure that this never happens is to wrap components which contain client-only code in a next/dynamic in order to force them to load on the client side, here's a simple example of how to do that:

import dynamic from 'next/dynamic';

const DynamicAblyComponent = dynamic(() => import('./path/to/your/ably/component'), {
  ssr: false, // this ensures that server side rendering is never used for this component
})

export default DynamicAblyComponent;

If the above solution doesn't work for you, there are a few alternatives documented here.

It's worth mentioning also that, while the name 'Client Components' (ie components with the 'use client' directive) implies that these components will only be rendered on the client side, NextJS may still run the component code on the server in order to pre-render HTML so you may still need to use dynamic loading in order to avoid Ably clients being created on the server side.

I hope this clears things up, please let us know here if you have any further questions 🙂

@starlight-akouri
Copy link

There is something more dastardly going on here that really underscores the importance of using dynamic import for your client-side ably. If you are seeing phantom connections/subscribers on your ably dashboard this could be the reason why.
When I switched to using next/dynamic, I saw that my "max connections" was not linearly increasing.

I am still trying to figure out how to export my Realtime client directly using this next/dynamic realm without having to create a custom component for each use case I want to connect client-side.

@sikula
Copy link

sikula commented Sep 10, 2023

@starlight-akouri Let me know if you find a solution. I'm using Remix and it doesn't have dynamic function like nextjs, so I'm running into a similar issue as you I think.

@owenpearson
Copy link
Contributor

@starlight-akouri, I'm sorry to hear that you're still having issues here. It sounds like something in your application code is creating more ably-js clients than it should, but it's hard to say what the issue is without seeing some code. If you're able to share a repro I'd be happy to take a look?

@owenpearson
Copy link
Contributor

@sikula, it should be possible to achieve the same thing as next/dynamic in remix by using the ClientOnly component. Let me know if you have any issues with setting this up with Ably.

FWIW as briefly mentioned above, the fundamental issue here is that it's impossible to resolve a URL beginning with a / character on nodejs, so the issue should also go away if you set a fully qualified URL as your authUrl.

@abdullinmx
Copy link

@sikula, fyi I'm using Remix.run and it works fine with configureAbly hook. I've just wrapped it into a custom hook and ugly check for window


const useRTS = () => {
  const [configured, setConfigured] = useState(false);
  const hasWindow = typeof window !== 'undefined';
  useEffect(() => {
    if (hasWindow && !configured) {
      configureAbly({ authUrl: '/api/token' });
      setConfigured(true);
    }
  }, [hasWindow, configured]);
};

export default useRTS;

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

No branches or pull requests

10 participants