[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8059":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":19,"defaultBranch":20,"hasWiki":18,"hasPages":19,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":13,"lastSyncTime":25,"discoverSource":26},8059,"knock","nsarno\u002Fknock","nsarno","Seamless JWT authentication for Rails API",null,"Ruby",2054,255,2,42,0,59.22,"MIT License",true,false,"master",[],"2026-06-12 04:00:37","## DISCLAIMER\n\nThis project is not being maintained and I don't recommend using it in its current form.\nAs an alternative, I recommend using the [jwt](https:\u002F\u002Fgithub.com\u002Fjwt\u002Fruby-jwt) gem directly.\n\n# knock\n\n[![Gem Version](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fknock.svg)](http:\u002F\u002Fbadge.fury.io\u002Frb\u002Fknock)\n[![Build Status](https:\u002F\u002Ftravis-ci.org\u002Fnsarno\u002Fknock.svg)](https:\u002F\u002Ftravis-ci.org\u002Fnsarno\u002Fknock)\n[![Code Climate](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fnsarno\u002Fknock\u002Fbadges\u002Fgpa.svg)](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fnsarno\u002Fknock)\n\nSeamless JWT authentication for Rails API\n\n## Description\n\nKnock is an authentication solution for Rails API-only application based on JSON Web Tokens.\n\n## Getting Started\n\n### Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'knock'\n```\n\nThen execute:\n\n    $ bundle install\n\n### Requirements\n\nKnock makes one assumption about your user model:\n\nIt must have an `authenticate` method, similar to the one added by [has_secure_password](http:\u002F\u002Fapi.rubyonrails.org\u002Fclasses\u002FActiveModel\u002FSecurePassword\u002FClassMethods.html#method-i-has_secure_password).\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  has_secure_password\nend\n```\n\nUsing `has_secure_password` is recommended, but you don't have to as long as your user model implements an `authenticate` instance method with the same behavior.\n\n### Usage\n\nInclude the `Knock::Authenticable` module in your `ApplicationController`\n\n```ruby\nclass ApplicationController \u003C ActionController::API\n  include Knock::Authenticable\nend\n```\n\nYou can now protect your resources by calling `authenticate_user` as a before_action\ninside your controllers:\n\n```ruby\nclass SecuredController \u003C ApplicationController\n  before_action :authenticate_user\n\n  def index\n    # etc...\n  end\n\n  # etc...\nend\n```\n\nYou can access the current user in your controller with `current_user`.\n\nIf no valid token is passed with the request, Knock will respond with:\n\n```\nhead :unauthorized\n```\n\nYou can modify this behaviour by overriding `unauthorized_entity` in your controller.\n\nYou also have access directly to `current_user` which will try to authenticate or return `nil`:\n\n```ruby\ndef index\n  if current_user\n    # do something\n  else\n    # do something else\n  end\nend\n```\n\n_Note: the `authenticate_user` method uses the `current_user` method. Overwriting `current_user` may cause unexpected behaviour._\n\nYou can do the exact same thing for any entity. E.g. for `Admin`, use `authenticate_admin` and `current_admin` instead.\n\nIf you're using a namespaced model, Knock won't be able to infer it automatically from the method name. Instead you can use `authenticate_for` directly like this:\n\n```ruby\nclass ApplicationController \u003C ActionController::Base\n  include Knock::Authenticable\n\n  private\n\n  def authenticate_v1_user\n    authenticate_for V1::User\n  end\nend\n```\n\n```ruby\nclass SecuredController \u003C ApplicationController\n  before_action :authenticate_v1_user\nend\n```\n\nThen you get the current user by calling `current_v1_user` instead of `current_user`.\n\n### Configuration\n\n#### In the entity model\n\nThe entity model (e.g. `User`) can implement specific methods to provide\ncustomization over different parts of the authentication process.\n\n- **Find the entity when creating the token (when signing in)**\n\nBy default, Knock tries to find the entity by email. If you want to modify this\nbehaviour, implement within your entity model a class method `from_token_request`\nthat takes the request in argument.\n\nE.g.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  def self.from_token_request request\n    # Returns a valid user, `nil` or raise `Knock.not_found_exception_class_name`\n    # e.g.\n    #   email = request.params[\"auth\"] && request.params[\"auth\"][\"email\"]\n    #   self.find_by email: email\n  end\nend\n```\n\n- **Find the authenticated entity from the token payload (when authenticating a request)**\n\nBy default, Knock assumes the payload as a subject (`sub`) claim containing the entity's id\nand calls `find` on the model. If you want to modify this behaviour, implement within\nyour entity model a class method `from_token_payload` that takes the\npayload in argument.\n\nE.g.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  def self.from_token_payload payload\n    # Returns a valid user, `nil` or raise\n    # e.g.\n    #   self.find payload[\"sub\"]\n  end\nend\n```\n\n- **Modify the token payload**\n\nBy default the token payload contains the entity's id inside the subject (`sub`) claim.\nIf you want to modify this behaviour, implement within your entity model an instance method\n`to_token_payload` that returns a hash representing the payload.\n\nE.g.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  def to_token_payload\n    # Returns the payload as a hash\n  end\nend\n```\n\n- **Token Lifetime**\n\nBy default the generated tokens will be valid, after generated, for 1 day.\nYou can change it in the Knock configuration file (config\u002Fknock.rb),\nsetting the desired lifetime:\n\nE.g.\n\n```ruby\n  Knock.token_lifetime = 3.hours\n```\n\nIf you are generating tokens for more than one entity, you can pass\neach lifetime in a hash, using the entities class names as keys, like:\n\nE.g.\n\n```ruby\n  # How long before a token is expired. If nil is provided,\n  # token will last forever.\n  Knock.token_lifetime = {\n    user: 1.day\n    admin: 30.minutes\n  }\n```\n\n#### In the initializer\n\nRead [lib\u002Fknock.rb](https:\u002F\u002Fgithub.com\u002Fnsarno\u002Fknock\u002Fblob\u002Fmaster\u002Flib\u002Fknock.rb) to learn about all the possible configuration options and their default values.\n\nYou can create an initializer like in the example below:\n\nInside `config\u002Finitializers\u002Fknock.rb`\n\n```ruby\nKnock.setup do |config|\n  config.token_lifetime = 1.hour\n\n  # For Auth0\n  config.token_audience = -> { Rails.application.secrets.auth0_client_id }\n  config.token_secret_signature_key = -> { JWT.base64url_decode Rails.application.secrets.auth0_client_secret }\nend\n```\n\n### Authenticating from a web or mobile application\n\nExample request to get a token from your API:\n\n```\nPOST \u002Fuser_token\n{\"auth\": {\"email\": \"foo@bar.com\", \"password\": \"secret\"}}\n```\n\nExample response from the API:\n\n```\n201 Created\n{\"jwt\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\"}\n```\n\nTo make an authenticated request to your API, you need to pass the token via the request header:\n\n```\nAuthorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\nGET \u002Fmy_resources\n```\n\nKnock responds with a `404 Not Found` when the user cannot be found or the password is invalid. This is a security best practice to avoid giving away information about the existence or not of a particular user.\n\n**NB:** HTTPS should always be enabled when sending a password or token in your request.\n\n### Authenticated tests\n\nTo authenticate within your tests:\n\n1. Create a valid token\n2. Pass it in your request\n\ne.g.\n\n```ruby\nclass SecuredResourcesControllerTest \u003C ActionDispatch::IntegrationTest\n  def authenticated_header\n    token = Knock::AuthToken.new(payload: { sub: users(:one).id }).token\n\n    {\n      'Authorization': \"Bearer #{token}\"\n    }\n  end\n\n  it 'responds successfully' do\n    get secured_resources_url, headers: authenticated_header\n\n    assert_response :success\n  end\nend\n```\n\n#### Without ActiveRecord\n\nIf no ActiveRecord is used, then you will need to specify what Exception will be used when the user is not found with the given credentials.\n\n```ruby\nKnock.setup do |config|\n\n  # Exception Class\n  # ---------------\n  #\n  # Configure the Exception to be used (raised and rescued) for User Not Found.\n  # note: change this if ActiveRecord is not being used.\n  #\n  # Default:\n  config.not_found_exception_class_name = 'MyCustomException'\nend\n```\n\n### Algorithms\n\nThe JWT spec supports different kind of cryptographic signing algorithms.\nYou can set `token_signature_algorithm` to use the one you want in the\ninitializer or do nothing and use the default one (HS256).\n\nYou can specify any of the algorithms supported by the\n[jwt](https:\u002F\u002Fgithub.com\u002Fjwt\u002Fruby-jwt) gem.\n\nIf the algorithm you use requires a public key, you also need to set\n`token_public_key` in the initializer.\n\n## CORS\n\nTo enable cross-origin resource sharing, check out the [rack-cors](https:\u002F\u002Fgithub.com\u002Fcyu\u002Frack-cors) gem.\n\n## Related links\n\n- [10 things you should know about tokens](https:\u002F\u002Fauth0.com\u002Fblog\u002F2014\u002F01\u002F27\u002Ften-things-you-should-know-about-tokens-and-cookies\u002F)\n\n## Contributing\n\n1. Fork it ( https:\u002F\u002Fgithub.com\u002Fnsarno\u002Fknock\u002Ffork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## License\n\nMIT\n","Knock 是一个为 Rails API 应用程序提供无缝 JWT 认证的解决方案。其核心功能包括通过 JSON Web Tokens 实现用户认证，支持自定义认证方法，并且能够轻松地保护控制器中的资源。技术特点上，Knock 依赖于用户模型中实现的 `authenticate` 方法，推荐使用 `has_secure_password`，但不强制要求。适用于需要基于 JWT 的简单而有效认证机制的 Rails API 项目。不过需要注意的是，该项目已不再维护，建议考虑直接使用 [jwt](https:\u002F\u002Fgithub.com\u002Fjwt\u002Fruby-jwt) gem 作为替代方案。","2026-06-11 03:15:52","top_language"]