Giter VIP home page Giter VIP logo

firebase_id_token's Introduction

firebase_id_token's People

Contributors

ababich avatar arkhwise avatar dps avatar fschuindt avatar guilhermefeitoza-id avatar metekabak avatar penguinwokrs avatar rromanchuk avatar socio-mehmet avatar thornomad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

firebase_id_token's Issues

I want to write a test easily

hello.
Before replacing it with another on redis, I realized it was hard to test when using it with Rails.
I'm happy if you merge. 🙇

PR #14

Running the gem without Redis?

Hi! Thanks for the gem! I would love to use it but am hesitant to introduce Redis as a dependency just so I can verify Firebase tokens...is there any way I can not use Redis and have the gem work?

Rather than auto update certs, or a cron job. consider Rails.cache.fetch?

I was messing around with the gem and it seems like it'd be pretty easy to use Rails.cache.fetch to pull in the new certs if they're expired.

I see a few pros and cons:

Pros:

  • no cron job, if the certificate ttl is expired, Rails.cache.fetch could just pull in the new certs and store them in one step
  • no cache stampeding: rails caching has a built in option called race_condition_ttl that could be used to prevent multiple requests from fetching the certs at the same time.
  • no redis dependency (will just use whatever cache store is being set in the app config, although i prefer redis as well)

Cons:

  • doesn't appear there is an explicit rails dependency right now, but this approach would introduce one.

FirebaseIdToken::Signature.verify(token) returns nil for newly issued tokens

Using this library, newly issued tokens don't verify correctly until one second after they have been issued.

Found using a client example which did a forceRefresh on the token every time - had a timing dependent bug where these tokens sometimes verified OK but mostly didn't.

    def still_valid?(payload)
      payload['exp'].to_i > Time.now.to_i &&
      payload['iat'].to_i < Time.now.to_i
    end

Should be payload['iat'].to_i <= Time.now.to_i

Fix the Code Climate test coverage report

report issue

As shown in this image, the test coverage report by Code Climate is "unknown". I don't know what's happening and have little time to investigate at the moment. But I think it's worth to be mentioned here.

Anyone interested into tackling it can use your own Code Climate account, let me know if anything is needed from me.

Have to sleep in order for verify to work

I was wondering if you had any thoughts on this:

def login
  sleep(2)

  decoded = verify_token(params[:token])
  puts(decoded)

  json_response(firebase_data: decoded)
end

def verify_token(token)
  FirebaseIdToken::Signature.verify(token)
end

^works

def login

  decoded = verify_token(params[:token])
  puts(decoded)

  json_response(firebase_data: decoded)
end

def verify_token(token)
  FirebaseIdToken::Signature.verify(token)
end

^ not work :( firebase_data is null

Difficulties to run tests

Hi,
I have some difficulties to run the tests as expected in the doc.

I have a controller test : domains_controller_test.rb

`
require 'test_helper'

module Api

module V1

class DomainsControllerTest < ActionController::TestCase

  setup do
    #@routes = Engine.routes
    #@user = users(:one)
  end
    
  def create_token(sub: nil)
    _payload = payload.merge({sub: sub})
    JWT.encode _payload, OpenSSL::PKey::RSA.new(FirebaseIdToken::Testing::Certificates.private_key), 'RS256'
  end

  def payload
    # payload.json
  end

  test 'should success get api v1 users ' do
    get :show, headers: create_token(@user.id)
    assert_response :success
  end
end

end
end`

When I run the test, I have this error

test_should_success_get_api_v1_users_#Api::V1::DomainsControllerTest (0.03s)
NameError: NameError: uninitialized constant Api::V1::DomainsControllerTest::Engine
test/controllers/domains_controller_test.rb:7:in `block in class:DomainsControllerTest

I don't know if it's an error from my rails tests configuration. After some researches on rails Engines and on this type of error on stackoverflow, I didn't found how to figure it out.
It may come from my misunderstanding of some basic Rails stuffs.
Maybe the FirebaseIdToken.test! should init an Engine ?
When I comment the setup of the test case and hard code
get :show, headers: create_token(1)
I get an
ArgumentError: wrong number of arguments (given 1, expected 0)
So I tried
get :show, headers: create_token() NoMethodError: undefined method 'merge' for nil:NilClass

So I am looking for where the payload variable is initialized. I'am stuck there, so I try to have some help to understand what I'am doing wrong.

Thank you for your help.

Emeric

FirebaseIdToken::Signature.verify(Token) always nil

Hi, firstly thanks you for your library. I am working in a rails API that authenticate the users in an Android app using Google and Facebook login and giving a firebase token when the users log in the app. I send this token to the server API and i try to verify the token using the method FirebaseIdToken::Signature.verify(Token) but always returned nil.

I have followed the instructions in the main page of your gitHub project, installing and setting up all the requeriments, but i still have the same problem.

I have been thinking in the possibility that the problem is at the config file (firebase_id_token.rb), because i am not sure if the firebase-project-id its what i think it is.
FirebaseIdToken.configure do |config|
config.project_ids = [myproject-7839d]
end

Getting the firebase-project-id from:
project-id

Thanks u a lot for the help.

SSL_connect Failure for Heroku Redis 6 Premium

Getting the following failure when firebase_id_token processes are run.
Using redis 6 Premium tier on Heroku which forces secure TLS connections.

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 peeraddr=52.3.18.23:26249 state=error: certificate verify failed (self signed certificate in certificate chain)

redis.rb configuration file is set to VERIFY_NONE as suggested in heroku documentation
$redis = Redis.new(url: url, driver: :ruby, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })

Firebase_id_token works when redis is not forcing secure connections.

Full stack

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 peeraddr=52.3.18.23:26249 state=error: certificate verify failed (self signed certificate in certificate chain)
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/connection/ruby.rb:264:in connect_nonblock' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/connection/ruby.rb:264:in connect'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/connection/ruby.rb:306:in connect' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:385:in establish_connection'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:115:in block in connect' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:344:in with_reconnect'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:114:in connect' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:417:in ensure_connected'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:269:in block in process' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:356:in logging'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:268:in process' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/client.rb:161:in call'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis.rb:270:in block in send_command' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis.rb:269:in synchronize'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis.rb:269:in send_command' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-4.8.0/lib/redis/commands/strings.rb:191:in get'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-namespace-1.10.0/lib/redis/namespace.rb:558:in wrapped_send' /opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-namespace-1.10.0/lib/redis/namespace.rb:515:in call_with_namespace'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/redis-namespace-1.10.0/lib/redis/namespace.rb:389:in block (2 levels) in <class:Namespace>' /opt/homebrew/lib/ruby/gems/3.1.0/gems/firebase_id_token-2.4.0/lib/firebase_id_token/certificates.rb:181:in read_certificates'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/firebase_id_token-2.4.0/lib/firebase_id_token/certificates.rb:159:in initialize' /opt/homebrew/lib/ruby/gems/3.1.0/gems/firebase_id_token-2.4.0/lib/firebase_id_token/certificates.rb:66:in new'
/opt/homebrew/lib/ruby/gems/3.1.0/gems/firebase_id_token-2.4.0/lib/firebase_id_token/certificates.rb:66:in request!' /Users/garrettglover/development/Kidletcare/kidletcare_api/lib/tasks/firebase.rake:10:in block (3 levels) in

'
Tasks: TOP => firebase:certificates:force_request

Versions
ruby '3.1.2'
gem 'rails', '> 7.0.3'
gem 'redis', '
> 4.2', '>= 4.2.5'
gem 'firebase_id_token', '~> 2.4.0'

redis_cache_store conflict

Cannot use redis_cache_store option with your gem,
Is there a way to you update your redis requirements to 4?

Thanks

unable to decode a valid token (used for firebase google sign in)

JWT.decode(token, cert_key, true, JWT_DEFAULTS).first

I do have valid latest certificates from Google APIs stored in Redis. The above method is throwing the following error.

>       JWT.decode(token, cert_key, true, {:algorithm=>"RS256", :verify_iat=> false})
Traceback (most recent call last):
        2: from (irb):28
        1: from (irb):29:in `rescue in irb_binding'
JWT::VerificationError (Signature verification raised)

I used google sign in flutter library and generated an id token. The decoded ID Token appears similar to following:

{
  "name": "Mission Impossible",
  "picture": "https://lh3.googleusercontent.com/a-/AzyxwvutsrqponmlkjihgfedcbaZ=s94-12-16c",
  "iss": "https://securetoken.google.com/my-app",
  "aud": "my-app",
  "auth_time": 1620067560,
  "user_id": "iDdVVuTsRQppprfHzyxwjkcX383",
  "sub": "iDdVVuTsRQppprfHzyxwjkcX383",
  "iat": 1620067560,
  "exp": 1620071160,
  "email": "[email protected]",
  "email_verified": true,
  "firebase": {
    "identities": {
      "google.com": [
        "106342823543215321"
      ],
      "email": [
        "[email protected]"
      ]
    },
    "sign_in_provider": "google.com"
  }
}

looks like the same structure this library is expecting. any clue why I'm getting an invalid signature error when the library is trying to decode the token?

[advice] redis fatal

It's probably related to my development environment but i'm getting the following error when running FirebaseIdToken::Certificates.request!

Redis::ProtocolError: Got 'H' as initial reply byte. If you're in a forking environment, such as Unicorn, you need to connect to Redis after forking.

Just wondering if you have seen this before? I'll do some more digging

Error calling FirebaseIdToken.test! on 2.3.1

Hi,

Using gem version 2.3.1 I can't use FirebaseIdToken.test! anymore. It always give me this error:

Errno::ENOENT:                                                                                                
        No such file or directory @ rb_sysopen - /home/michel/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/firebase_id_token-2.3.1/spec/fixtures/files/jwt.json

Looking at the files released on 2.3.1 it seems like the folder spec is really missing:

tar xf firebase_id_token-2.3.1.gem
tar ltf data.tar.gz
.gitignore
.rspec
.travis.yml
.yardopts
CODE_OF_CONDUCT.md
Gemfile
LICENSE.txt
README.md
Rakefile
bin/console
bin/setup
firebase_id_token.gemspec
lib/firebase_id_token.rb
lib/firebase_id_token/certificates.rb
lib/firebase_id_token/configuration.rb
lib/firebase_id_token/exceptions/certificates_request_error.rb
lib/firebase_id_token/exceptions/certificates_ttl_error.rb
lib/firebase_id_token/exceptions/no_certificates_error.rb
lib/firebase_id_token/signature.rb
lib/firebase_id_token/testing/certificates.rb
lib/firebase_id_token/version.rb

New caching doesn't honor request! calls

#33 introduced new caching functionality to store certificates in memory. However, it breaks the gem in many ways, because the in-memory caching isn't refreshed when you call request!, which results in different threads and/or processes having different certificates after request!.

I'd suggest to rollback the functionality and leave local caching implementation to the applications (since you can't refresh a local cache if the certificates are updated in other process without using a shared storage).

Doc suggestion for tests

Hi,

I've been struggling today with the implementation of my tests with rspec, which would not pass even using the FirebaseIdToken.test! and the pretty cool code snippet explaining how to generate a token in test mode.

In order for the FirebaseIdToken::Signature.verify method to return a payload, it has to be valid, which implies 4 things to be in order in the test payload that's encrypted for token generation:

  • iat timestamp value before the test running time
  • exp timestamp value after the test running time
  • aud string to contain the project id
  • iss string to contain a url that depends on the project id

This error is invisible when testing with custom payload that's not a Google-generated token from actual firebase project.

It would be nice to add in the Test section of the documentation something that reminds of those requirements for a valid test payload.

Auto-update certificates

Imagine, you do not want to deal with cron and other periodic schedulers

What about automatically update certificates during single request if ttl <= configured_threshold

To prevent multiple instances to update in parallel it is simple to introduce some Redis-based lock

Dynamic Project Ids

Thanks for this great gem. It really very helpful for known projects ids. But for dynamic project id(s) this gem is not thread safe. In our case we have so much firebase projects on our database associated spesific users. As a workaround we monkey-patched the gem like the following:

module FirebaseIdToken
  def self.configuration
    Thread.current[:__fid_configuration] ||= Configuration.new
  end

  # Resets Configuration to defaults.
  def self.reset
    Thread.current[:__fid_configuration] = Configuration.new
  end
end

With this setup the following code sample is thread safe:

  pool = ConnectionPool.new(size: 100) { Redis.new url: ENV['REDIS_URL'] }

  Array(0..100).each do |project_id|
    Thread.new(project_id) do |project_id|
      pool.with do |conn|
        FirebaseIdToken.configure do |config|
          config.project_ids = [project_id]
          config.redis = conn
        end

        FirebaseIdToken::Certificates.request
        FirebaseIdToken::Signature.verify(token)
      end
    end
  end

In our use case this patch worked. If there is alternative approach, it is welcome. Otherwise I can create pull request including this monkey patched code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.