CodementorIO / rest-firebase

Ruby Firebase REST API client built on top of rest-core
Apache License 2.0
107 stars 22 forks source link

Missing claim 'kid' in auth header. #12

Open jrasanen opened 8 years ago

jrasanen commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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

jigarius commented 8 years ago

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 commented 8 years ago

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": "firebase@example.gserviceaccount.com",
  "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:

Hope this helps.

jrasanen commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

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

godfat commented 8 years ago

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

Questions:

jigarius commented 8 years ago

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)" < notifications@github.com> 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 https://github.com/CodementorIO/rest-firebase/issues/12#issuecomment-226108134, or mute the thread https://github.com/notifications/unsubscribe/AEFmUcEb6Rm4fzP66Afw1zomMhhbEU_rks5qL6fvgaJpZM4Ioawp .

jrasanen commented 8 years ago

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 commented 8 years ago

Thanks for the update!!

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

jrasanen commented 8 years ago

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

jrasanen commented 8 years ago

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

bhuvangu commented 8 years ago

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

bhuvangu commented 8 years ago

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 commented 5 years ago

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 commented 4 years ago

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 commented 4 years ago

Any update on this issue

godfat commented 4 years ago

Unfortunately, nothing from me

khuongphp commented 4 years ago

Same with https://github.com/kreait/firebase-php/issues/169#issuecomment-366950404 There are 3 token type. But firebase only verify token from client app.

bdmostafa commented 2 years ago

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