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

Missing claim 'kid' in auth header. #12

Open
jrasanen opened this issue May 27, 2016 · 23 comments
Open

Missing claim 'kid' in auth header. #12

jrasanen opened this issue May 27, 2016 · 23 comments

Comments

@jrasanen
Copy link

On Firebase 3.0 I get an error "Missing claim 'kid' in auth header."

Apparently now Firebase requires private key's id supplied with claims.

@godfat
Copy link
Contributor

godfat commented May 27, 2016

Hi, I'll check this tomorrow. In the mean time, could you please let me know if this is only for some latest setting, not that this breaks everything?

@godfat
Copy link
Contributor

godfat commented May 28, 2016

Since I no longer use firebase, could you please let me know if this is the only thing we need to change?
That is, the way to generate auth?

https://firebase.google.com/docs/auth/server#use_a_jwt_library

godfat added a commit that referenced this issue May 29, 2016
@jigarius
Copy link

jigarius commented Jun 2, 2016

I am using PHP-JWT to generate the token. Where does this kid go? Can anybody kindly help?

    "iss" => $service_email,
    "sub" => $service_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now,
    "exp" => $now + (60 * 60),
    "uid" => $fbid,
    "claims" => array(
        'kid' => 'Key ID',
        'provider' => 'drupal',
    ),

Is it supposed to be inside claims or is it supposed to be at the same level as uid?

@jrasanen
Copy link
Author

jrasanen commented Jun 2, 2016

For future reference.

I got Firebase 3.0 working like this:

You get this service account manifest JSON through Google's IAM console.

{
  "type": "service_account",
  "project_id": "..redacted..",
  "private_key_id": "..redacted..",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...redacted...\n-----END PRIVATE KEY-----\n",
  "client_email": "[email protected]",
  "client_id": "12340000000000000000",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
}
def generate_web_token(uid, claims)
  # Parses Google's `service_account` JSON file into an array
  service_data = get_service_data()

  private_key = OpenSSL::PKey::RSA.new(service_data['private_key'])

  service_account_email = service_data['client_email']
  now_seconds = Time.now.to_i

  payload = {
    iss: service_account_email,
    sub: service_account_email,
    aud: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
    iat: now_seconds,
    exp: now_seconds + (60 * 60),
    uid: uid,
    claims: claims,
    kid: data['private_key_id']
  }

  private_key = OpenSSL::PKey::RSA.new(service_data['private_key'])

  # Generate JWT
  JWT.encode(payload, private_key, 'RS256')
end

My other findings:

  • For what I tested, as for now Firebase ignores the exp parameter and sets/forces it to 1 hour, regardless what you put there, I tried to get it to 30 min but when you read the token back after authenticating, it's 3600 seconds.
  • To get the real reason why token did not work, monitor for POST XHR to endpoint 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=...' in your browser's dev tools. If the token was OK, it returns when it expires (3600 seconds) and a refreshToken (couldn't find what this is for).
  • Make sure your frontend api key matches the domain you have whitelisted on Firebase's panel. (CREDENTIAL_MISMATCH error returned by that verifyCustomToken post call if domain doesn't match to what you initialize in initializeApp)

Hope this helps.

@jrasanen
Copy link
Author

jrasanen commented Jun 2, 2016

@godfat thanks for the fix! I'll try to find time to test it tomorrow, it looks like it'll work.

Also reference for everybody: 2.4.X version of Firebase will be supported for some time according to devs.

@jigarius
Copy link

jigarius commented Jun 2, 2016

I am passing it as you described - It should work. However, it does not work :( It still gives me a 400 Bad Request saying Invalid claim 'kid' in auth header. And there is no documentation on kid in the Firebase Docs. Now I'm starting to get worried. Such a waste of time for such a simple thing. Thanks for the answer, buddy.

@godfat
Copy link
Contributor

godfat commented Jun 2, 2016

@jrasanen I didn't figure out how to solve that kid issue for that commit and I can't find any document for that either :( Fortunately you found it! I'll try your approach in the next few days. Thanks!

Bottom line: As long as you could pass auth for rest-firebase, I guess it would still work for 3.0.

@jrm1987 Oh, sorry about that :( They said they would improve the doc.

@godfat
Copy link
Contributor

godfat commented Jun 3, 2016

It didn't work for me either. However, I tried to put a kid into JWT header, then Firebase would give me:

{"error"=>"Invalid claim 'kid' in auth header."}

I tried to give private_key_id, project_id, client_id, but none of them worked. Oh silly kid. Please stop kidding me.

@katowulf
Copy link

Some possible answers here and the required attributes (including the kid attribute) are described here

@godfat
Copy link
Contributor

godfat commented Jun 15, 2016

@katowulf Thanks! I still don't get it though. Still getting {"error"=>"Invalid claim 'kid' in auth header."}

Questions:

  • Should I fill sub with uid? But actually I have no idea what's uid. Who is the user? I don't think I have any users in my testing project. How do I get any user id?
  • Should I also pass uid even with sub? We pass the same values for both of them?
  • It's not clear what's kid. Was that the private key (that pem) for this project?
  • Do we still pass claims?

@jigarius
Copy link

Firebase support team wrote me today that they are looking into the error
and will inform when they have a solution.
El 15 jun. 2016 2:21 a. m., "Lin Jen-Shin (godfat)" <
[email protected]> escribió:

@katowulf https://github.com/katowulf Thanks! I still don't get it
though. Still getting {"error"=>"Invalid claim 'kid' in auth header."}

Questions:

  • Should I fill sub with uid? But actually I have no idea what's uid.
    Who is the user? I don't think I have any users in my testing project. How
    do I get any user id?
  • Should I also pass uid even with sub? We pass the same values for
    both of them?
  • It's not clear what's kid. Was that the private key (that pem) for
    this project?
  • Do we still pass claims?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#12 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AEFmUcEb6Rm4fzP66Afw1zomMhhbEU_rks5qL6fvgaJpZM4Ioawp
.

@jrasanen
Copy link
Author

Meh, the code which I was using as a workaround stopped working and Google/Firebase started returning:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalid",
    "message": "INVALID_CUSTOM_TOKEN"
   }
  ],
  "code": 400,
  "message": "INVALID_CUSTOM_TOKEN"
 }
}

@godfat
Copy link
Contributor

godfat commented Jun 17, 2016

Thanks for the update!!

I guess our best bet for now is just waiting, unless it's urgent to adopt...

@jrasanen
Copy link
Author

Waiting is good, too bad though. Firebase seriously needs a debug console, so devs can see what is happening on their side.

@jrasanen
Copy link
Author

Though, I just noticed poking Firebase that the tokens they return have "kid" attribute in JWT's header, not in payload/data:
image

@bhuvangu
Copy link

Hi any update on the issue @breft did you got a response from firebase guys

@bhuvangu
Copy link

Original post: http://stackoverflow.com/questions/39117237/firebase-rest-with-auth-query-param-not-working
From: FirebaseSupport team

Yes, creating custom tokens using FirebaseAuth.getInstance().createCustomToken(uid, additionalClaims) does not work with REST API. These tokens are designed to be used by client SDKs with signInWithCustomToken(token). Please note that "client to DB" REST requests are not supported right now due to changes in security model in the new Firebase (legacy Firebase supports it).

As you have pointed out, you need to follow this link in order to make an authenticated REST request. You should to use the access_token parameter, passing the token derived from the service account private key. This assumes you're scenario is "Server to DB" as you're using a service account.

To add custom claims using REST, you should use the auth_variable_override parameter. See here. Your request should now look like this with the added claim: {"uid":"6LiF16Dm0hNB9XO61UR1KM5Jeun2"}

$ curl "https://test-de98f.firebaseio.com/test.json?access_token=&auth_variable_override=%7B%22uid%22%3A%226LiF16Dm0hNB9XO61UR1KM5Jeun2%22%7D"
{" 1213314":{"alanisawesome":"Alan Turing"}}

I do understand that the documentation you have pointed out needs to be improved and have raised this to our documentation team so that it could be prioritized appropriately. Though, I can't share any timelines as of the moment.

Hope this helps. Feel free to respond for any more issues or concerns.

@rnanania
Copy link

rnanania commented Mar 2, 2019

During the "verifyPassword" API use this parameter "returnSecureToken":true along with email and password. This worked for me.
screen shot 2019-03-02 at 3 57 07 pm

@SohaibKtb
Copy link

i am fetching the products for a specific user in this way:

Future<bool> fetchProducts() async {
    _isLoading = true;
    notifyListeners();
    try{
    final http.Response response = await http
        .get('https://flutter-products-d07d8.firebaseio.com/products.json?auth=${_authenticatedUser.token}');
        print(response.body);
      final List<Product> fetchProductList = [];
      final Map<String, dynamic> productListData = json.decode(response.body);
      if (productListData == null) {
        _isLoading = false;
        notifyListeners();
        return false;
      }
      productListData.forEach((String productId, dynamic productData) {
        final Product product = Product(
          id: productId,
          title: productData['title'],
          description: productData['description'],
          image: productData['image'],
          price: productData['price'],
          userEmail: productData['userEmail'],
          userId: productData['userId'],
        );
        fetchProductList.add(product);
      });
      _products = fetchProductList;
      _isLoading = false;
      notifyListeners();
      _selProductId = null;
      return true;
    }catch (error) {
      _isLoading = false;
      notifyListeners();
      return false;
    }
  }

but i am getting this response:

I/flutter (16571): "error" : "Invalid claim 'kid' in auth header: 'skIBNg' with iat: '1569414381'"

can any one help me please

@itzzmeakhi
Copy link

Any update on this issue

@godfat
Copy link
Contributor

godfat commented Feb 25, 2020 via email

@khuongphp
Copy link

Same with kreait/firebase-php#169 (comment)
There are 3 token type.
But firebase only verify token from client app.

@bdmostafa
Copy link

I solved my this same type of error adding returnSecureToken: true in body object while logging with email and password and it works fine

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

No branches or pull requests

10 participants