-
Notifications
You must be signed in to change notification settings - Fork 903
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
HTTPS Callable context.auth
is null
after updating to latest packages (-tools 11.16)
#5210
Comments
@chinesehemp I may misunderstand, but renaming an unused argument isn't going to help (because a.) the name is irrelevant and b.) in any case it isn't used). Perhaps you could please clarify what you were thinking might help? |
@brianmhunt I had a similar issue with the emulator and https.onCall functions where I only included context as the arg. So inside the function, I was also finding context.auth was coming back as null. After I included data in the args with context, somehow the function was able to return context.auth again. Not sure exactly why it was happening, but it worked. I thought maybe it might work for you too. I'm using firebase-cli 11.16.0 FYI. |
context.auth
is nullcontext.auth
is null
after updating to latest packages (-tools 11.16)
Here's the most trivial repro: export const ping2 = functions.https.onCall((a, b) => console.log({a, b})) ... and call with > firebaseFunctions.httpsCallable('ping2')() The results are:
Version / DevTools:
I'll try to create a repo to demonstrate this but it's a bit odd that everyone using the library isn't encountering this. |
Interestingly, even after downgrading all the packages the problem continues to exhibit i.e. reverting the following updates:
|
What's particularly peculiar is that the but in firebase-functions/lib/common/providers/https.js@checkAuthToken: we don't see that header:
... suggesting it's being scrubbed somewhere. |
Possibly related: #2910 |
It looks suspiciously like the problem is intertwined with |
Noting that if I add logging at await runFunction(() => {
console.log(`⭐️ ⭐️ args `, args[0], args[1])
return trigger(args[0], args[1]);
}); I see logging that includes the Authorization Bearer token:
So the authorization header would seem to be removed between the start/end points on the stack trace:
|
Traceback
|
|
In the There wasn't much that stood out but here's what I get when I trigger the function with
|
@brianmhunt Thanks for a very detailed investigation. I read over the issue, and while I don't yet have answer to why this is happening in your setup, I've got some clues that might help us:
("That's sounds complicated!" you might say. We needed a way for the onCall handler to work with the request with unsigned authorization token to make it easy to generate fake auth tokens. Today the Admin and Functions SDK both natively support running in emulator environment, so in theory we don't need such a trick. But old code still remains). Given that your screenshot includes Can you share a little more about:
Can you reproduce the issue by doing something like this? |
@taeold Thanks for the detailed description, this makes a lot of sense. I had essentially come to a conclusion about monkey patching (and legacy code). Your asking about the directories also seems insightful, since this seemingly isn't occurring for everyone I was looking for some distinguishing factor. We are in a monorepo so the directory structure is different from most, which might be that factor. We have tried Node 16.14 and 16.18.1 (on Mac OSX, Ubuntu and Debian). 1. Directory StructureHere's the setup of the directories where relevant things are being installed (and I can post more/others if needed):
[1] /package.json
[2] /services/end-to-end-tests/package.json
(I pinned firebase-tools to 11.16.0 as part of this investigation) [3] services/end-to-end-tests/emulator/firebase.json
[4] /services/firebase/functions/package.json
2. CURL request/reply$ URL=http://localhost:7902/demo-minutebox-emulation/us-central1/userFunctions-ping
$ curl -X POST -H "Authorization: Bearer eJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" -H "content-type: application/json" -d '{"data": {"n": 20}}' $URL
{"result":{"status":"ok","userID":"1234567890","userEmail":null,"now":"2022-11-18T12:43:08.621Z"}} Where the trivial function is (roughly, pared down a bit here for brevity): function ping ({ context, projectID }) {
return {
status: 'ok',
userID: context.auth ? context.auth.uid : null,
userEmail: context.auth ? context.auth.token.email : null,
now: new Date().toISOString(),
}
}
functions.runWith(runWith).region(REGION).https.onCall(async (params, context) => ping(context) What's interesting is that we see the I'm pretty ramped up on this problem, and it's quite important to us, so happy to dig deeper. |
@taeold Sorry to ping, but just wanted to see if there's more information/investigation I might be able to provide on this issue, or if you have any hints as to what (monkey-patching) functions in the code might be worth looking at deeper. Thanks |
@brianmhunt Sorry I dropped the ball on this issue.
Sadly this makes things even more confusing. So it looks like the auth context is available in the minimal example you've given, yet it is NOT available in the callable function that you are debugging. I along with couple of other engineers in the team tried to reproduce the issue you are seeing here without success. If there is a minimal "project" setup that you can share to reproduce the issue, that'd help us investigate the issue tremendously. Couple of shorts in the dark:
Note that |
I'm running into the exact same problem on a very fresh project. I did a fresh install last week, and now that I'm writing my first callable functions... no The repro is to
Here's my
|
Heres my
And here's the
Note that I'm using |
@taeold Thanks, it is weird. On your questions:
The chief thing I think it might be smart to eliminate is whether the JWT being generated by the auth emulator is being rejected as unsigned, etc. How did you sign your sample JWT above [1]? jwt.io says if fails owing to a missing secret: The JWT that I posted has algo:
These differences feel material and are in-band, otherwise I suspect we'll need to look at some sort of weird side-effect e.g. from peer headers. Thanks @deltaepsilon for the repro instructions, that's excellent. It might be helpful to create a min-working-repro to expedite things, too (rather than the firebase devs having to block-and-copy everything). Thanks for the help on this. CC @LiutskoOlga [1] |
I'm experiencing what is likely a related issue. After upgrading firebase tools (or firebase npm packages, not exactly sure when it started) the firestore emulator semi-randomly decides to reject all queries and updates from my app. Sometimes it works without issue, other times it just rejects everything as though there is no authenticated user even when there is. Rolling back to This really is a critical blocking bug, the newest versions of the emulators are unusable and I unfortunately wasted a lot of time figuring out that there was something wrong with the emulators and not my app. |
Thanks @deltaepsilon, that's great. @taeold ^^ hopefully this repro makes this straightforward to diagnose & remedy. |
@taeold Just pinging on this, wondering if you've had a chance to try and repro it using the above github repo. |
I'm currently using this abomination to work around it: const xCallableContextAuth = context.rawRequest.headers['x-callable-context-auth'] as string ?? '';
const fakeAuth = decodeURIComponent(xCallableContextAuth);
const fakeAuthParsed = fakeAuth && JSON.parse(fakeAuth);
const userId = context.auth?.uid || fakeAuthParsed?.uid; |
I seem to have run into a similar issue. I don't know if I can add much to a resolution, but for me the problem only occurs after switching to 2nd gen functions (import via Happy to share any other details that might be relevant |
I created a workaround function that extracts auth off of the headers as necessary. It's working fine, although I wish they'd just patch their own code. import { https } from 'firebase-functions';
export function getContextAuth(context: https.CallableContext) {
const xCallableContextAuth = (context.rawRequest.headers['x-callable-context-auth'] as string) ?? '';
const fakeAuth = decodeURIComponent(xCallableContextAuth);
const fakeAuthParsed = fakeAuth && JSON.parse(fakeAuth);
const userId = context.auth?.uid || fakeAuthParsed?.uid;
return { userId };
} |
Hey folks, sorry that this issue fell under our radar. Using the sample repo that @deltaepsilon provided, I'm able to now reproduce this bug, and I'm going to dig into this a bit further. Thanks for your patience and sorry about the delay. |
After looking into the setup of the sample repo, I think that the problem might be using a yarn/monorepo setup. Basically, we have some code that tries to find the As it currently stands, firebase functions does not support monorepo (open issue for running I think yanking out our monkey-patching code would be the best course of action. But that would be a breaking change and would drop support for older versions of the SDK. |
@colerogers Thanks for the investigation and reporting.
It was working fine for us in a monorepo on I hope removing the monkey-patching is an option. I'd expect people who update firebase-tools to the latest also would be updating the SDK (but I've no evidence for this, only intuition 😁). |
The snippet I posted above is working great, so I'll stick with it for now. Hopefully other travelers can discover it and rescue themselves from auth hell. |
We just released firebase-functions v4.2.1 that includes a patch our SDK for unpacking I'll go ahead and mark this issue as closed |
This appears to be working @colerogers , many thanks for the update and the fix. |
@colerogers I just ran into the same issue using cloud functions gen 2. Switching to gen 1 fixed the problem. |
Same here, @colerogers will v2 get a similar fix at some point? |
Im running into the same issue after upgrading to v2 as well. |
the same issue with v2 ;( "firebase-functions": "4.4.1" |
Bumping, even today on April 18, 2024, I cannot access |
Hey folks, this is a pretty old closed issue and I don't usually monitor them. Usually it's best to open a new issue and link to a similar one as a reference, it's much easier for us to manage that way. Given that, I just tried out v2 callable functions and I'm not able to reproduce the bug. Just so we are clear, you'd need to be authenticated for the |
[REQUIRED] Environment info
firebase-tools:
Platform:
OS X 12.6
[REQUIRED] Test case
Run a trivial HTTPS callable function in the Functions Emulator. It does not have
context.auth
, as would be expected.[REQUIRED] Steps to reproduce
Listener:
Call with
functions.httpsCallable('ping')(),
[REQUIRED] Expected behavior
context.auth
have the expected credentials and output and emulator console show "Have auth" .[REQUIRED] Actual behavior
Emulator shows "Where's the auth?"
Related:
Packages / upgrade
This started occurring when we updated some packages, notably:
JWT Header
If we print the headers the authentication header has a proper (unsigned)
Bearer
token e.g. from jwt.ioDeploy vs emulator
The function works as expected when deployed, suggesting this is an emulator problem.
The text was updated successfully, but these errors were encountered: