{"id":22782198,"url":"https://github.com/randomstate/auth","last_synced_at":"2026-01-24T15:08:10.662Z","repository":{"id":110992388,"uuid":"125727205","full_name":"randomstate/auth","owner":"randomstate","description":"A framework-agnostic strategy-based approach to authentication for crystal-lang","archived":false,"fork":false,"pushed_at":"2018-03-21T20:09:15.000Z","size":22,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-23T16:18:18.977Z","etag":null,"topics":["authentication","crystal"],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/randomstate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-03-18T13:22:17.000Z","updated_at":"2024-02-28T06:00:59.000Z","dependencies_parsed_at":"2023-03-27T14:01:58.789Z","dependency_job_id":null,"html_url":"https://github.com/randomstate/auth","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/randomstate/auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randomstate%2Fauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randomstate%2Fauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randomstate%2Fauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randomstate%2Fauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/randomstate","download_url":"https://codeload.github.com/randomstate/auth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randomstate%2Fauth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28730310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","crystal"],"created_at":"2024-12-11T21:09:48.265Z","updated_at":"2026-01-24T15:08:10.655Z","avatar_url":"https://github.com/randomstate.png","language":"Crystal","funding_links":[],"categories":[],"sub_categories":[],"readme":"# auth\n\nA framework-agnostic strategy-based approach to authentication.\n\nFeatures:\n- Common strategies to rapidly implement common authentication workflows (WIP)\n- Easy-to-provide conversion between strategy users (such as a Firebase User) and your app user model\n- Default session storage and (ability for) retrieval\n- Create custom strategies with no required knowledge of app use-case\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  auth:\n    github: randomstate/auth\n```\n\n## Usage\n\n```crystal\nrequire \"auth\"\nrequire \"auth_firebase_jwt\" # or your favourite strategy implementation for this shard\n\n## Define required context for your app\n\n# 1) Enable type-safe support for your User class. This generates the appropriate strategy base classes to support your model. It *MUST* be called.\n# 2) List which strategies are supported. This sets up the auth manager class so that it can dynamically add and remove strategies by name. It *MUST* be called.\nAuth.define_user_class MyUserClass\nAuth.can_use Auth::Strategies::Firebase::JWT # , MyOtherStrategy, YetAnotherStrategyClass\n\n## Create an Auth::Manager instance\nmanager = Auth::Manager.new\n\n## Register your strategies with the manager\nfirebase_jwt = Auth::Strategies::Firebase::JWT.new \"project-1328\"\nmanager.use :jwt, firebase_jwt\n\n# Define how the strategy should convert the Firebase User to your own version\nfirebase_jwt.when_converting do | firebase_user |\n  user = MyUser.new # most likely you will fetch/upsert it from/in the database \n\n  user.email = firebase_user.email #etc\n  user # return your user instance\nend\n\n\n## Elsewhere in your app (most likely in a middleware)\nuser = manager.authenticate(:jwt, context) # context : HTTP::Server::Context\n\nif user.nil?\n  # not authenticated\nelse \n  # authenticated `MyUser` object\nend\n```\n\n### Quick Start with Amber Framework\n\nFollow the instructions (detailed above):\n- Call `Auth.define_user_class`\n- Call `Auth.can_use` with your strategies as parameters\n- Create an `Auth::Manager` instance\n- Register your strategies with the manager\n- Define how your strategy should convert to your custom user model\n\nThen add this to your `config/routes.cr` file in the pipes section for the relevant route:\n```crystal\nAuth::Pipe::Authenticate.new(manager, :strategy_name) # strategy_name is the symbol referencing your strategy, as defined when you registered your strategies with the manager\n```\n\nThis pipe will now guard any routes in the pipeline. It will raise an `Auth::Pipe::Unauthorized` exception if the user failed to authenticate. By default this will return a response with \"Unauthorized.\" and a status code of 401.\n\nInside your controller, you can now access the authenticated user like so:\n```crystal\nclass MyController \u003c ApplicationController\n\n  def index\n    authenticated_user = @context.user # typeof(authenticated_user) == (MyUser | Nil)\n  end\n\nend\n```\n\n## Development\n\n### Implementing Custom Strategies\n\n[[ TODO ]]\n\n## Contributing\n\n1. Fork it ( https://github.com/randomstate/auth/fork )\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## Contributors\n\n- [cimrie](https://github.com/cimrie) Connor Imrie - creator, maintainer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandomstate%2Fauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frandomstate%2Fauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandomstate%2Fauth/lists"}