{"id":19573004,"url":"https://github.com/npetkov/auth0_rails_frontend_example","last_synced_at":"2025-09-15T16:31:26.050Z","repository":{"id":14518719,"uuid":"76846432","full_name":"npetkov/auth0_rails_frontend_example","owner":"npetkov","description":"Sample Rails 6 project demonstrating the OAuth2 code grant flow using auth0","archived":false,"fork":false,"pushed_at":"2023-03-08T19:46:30.000Z","size":2101,"stargazers_count":1,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"dev","last_synced_at":"2024-11-11T06:38:38.690Z","etag":null,"topics":["auth0","cors","jwt","oauth2","omniauth","rails6","rails6-api"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/npetkov.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}},"created_at":"2016-12-19T09:11:31.000Z","updated_at":"2021-12-25T22:04:37.000Z","dependencies_parsed_at":"2024-11-11T06:41:48.106Z","dependency_job_id":null,"html_url":"https://github.com/npetkov/auth0_rails_frontend_example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npetkov%2Fauth0_rails_frontend_example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npetkov%2Fauth0_rails_frontend_example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npetkov%2Fauth0_rails_frontend_example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npetkov%2Fauth0_rails_frontend_example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/npetkov","download_url":"https://codeload.github.com/npetkov/auth0_rails_frontend_example/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233131533,"owners_count":18629559,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["auth0","cors","jwt","oauth2","omniauth","rails6","rails6-api"],"created_at":"2024-11-11T06:31:24.848Z","updated_at":"2025-09-15T16:31:20.718Z","avatar_url":"https://github.com/npetkov.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# README\n\nThis is a sample Rails 6 project demonstrating authentication with\n[auth0](https://auth0.com/). It requires an auth0 account (registration is free)\nand depends on a simple\n[API project](https://github.com/npetkov/auth0_rails_api_example). Please consult the\nreadme of that project for backend configuration. Below I'll assume that the API\nis served at `http://localhost:3001`.\n\nThe frontend content is extremely basic (vanilla javascript and no styles), as I\ndon't see any need to use an advanced framework/library for the purposes of this\ndemo/PoC.\n\nThe motivation behind this project is to provide a brief, concise introduction\nto JWT authentication using Rails. I've read through a lot of resources covering\ndifferent aspects of the topic so I decided to put them together in one working\nexample. The implementation is deliberately kept extremely sparse, as my goal\nisn't to present a state-of-the-art architecture but rather to illustrate a\nbasic OAuth2 code grant flow.\n\n## Installing Ruby and Rails\n\nPlease see [this section](https://github.com/npetkov/auth0_rails_api_example#installing-rbenv-and-ruby)\nof the API project documentation.\n## Installing `nvm` and Node LTS\n\nMy preferred method for installing Node versions is via `nvm`. Please refer to\nthe [documentation](https://github.com/nvm-sh/nvm) for the specific steps\nrequired on your operating system. The examples below illustrate how to install\na particular `nvm` version on Ubuntu:\n\n*  download and run the installer script:\n\n`wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash`\n\n* reload your shell profile:\n\n`source ~/.bashrc`\n\n* install the latest Node LTS version known to `nvm`:\n\n`nvm install --lts`\n\n* check the installed Node version:\n\n``` bash\n$ node -v\nv14.15.4\n```\n\n## Installing `yarn`\n\nAccording to the [official documentation(https://yarnpkg.com/getting-started/install),\nthe preferred way to install Yarn 2 is via `npm`:\n\n`npm install -g yarn`\n\nYou'll notice that this will install a `1.xx` version of the binary globally;\nthis is expected.\n## Project setup\n\nClone the repo and run the usual `bundle install`. I'm using ruby 3.0.0 and\ncan't guarantee that everything will work as expected with earlier versions.\n\nOnce all gems have been successfully installed, run `bin/setup`. This will\nensure everything is properly set up, including installing `yarn/npm` packages.\n\nIf you run into problems while compiling `node-sass` during the first `yarn`\nrun, take a closer look at the hints the error messages give away. These issues\nare rather common and there are a lot of resources online explaining how to\nresolve them.\n\nTo launch the server, use `bin/rails s`.\n\n*Side note: node-sass is a @rails/webpacker dependency in the 5.x branch. At the\ntime of writing, webpacker 6 is still in beta.*\n## Auth0 and API secret configuration\n\nThe project uses the Rails 6 encrypted credentials scheme. The project relies on\nthe following credentials being present:\n\n* __auth_domain__\n\n* __auth_client_id__\n\n* __auth_client_secret__\n\n* __api_identifier__\n\nYou can find the data for your application/API in the appropriate sections in\nthe auth0 dashboard. The screenshot below shows the settings page for an\nexample application. All the values needed can easily be copied over from there.\n\n![auth0 application](./.assets/auth0_app_config.png)\n\nIf you need guidance how to create the needed application and API in auth0,\nplease consult [this section](https://github.com/npetkov/auth0_rails_api_example#setting-up-an-auth0-application-and-api)\nof the API project documentation.\n\nIn order to edit the Rails application credentials, run `bin/rails credentials:edit`\nin the project root. If Rails complains about an unset `EDITOR` environmental\nvariable, append one to your shell profile and then source it to apply the\nchanges:\n\n``` bash\necho 'export EDITOR=vim' \u003e\u003e ~/.bashrc\nsource ~/.bashrc\n```\n\nPlease note that the master key used to encrypt the credentials is not under\nversion control. If you lose it, you'll have to recreate the credentials store.\n\n## Implementation notes - authorization and token retrieval\n\nThe projects uses the `omniauth` and `omniauth-auth0` gems, which perform the\n[Authorization Code Flow](https://auth0.com/docs/flows/authorization-code-flow)\nunder the hood. The whole configuration resides in a single initializer and uses\nthe credentials described in the previous section:\n\n``` ruby\nRails.application.config.middleware.use OmniAuth::Builder do\n  provider(\n    :auth0,\n    Rails.application.credentials.auth_client_id,\n    Rails.application.credentials.auth_client_secret,\n    Rails.application.credentials.auth_domain,\n    callback_path: '/auth/auth0/callback',\n    authorize_params: {\n      audience: Rails.application.credentials.api_identifier,\n      scope: 'openid email profile index:notes create:notes'\n    }\n  )\nend\n```\n\nThe initializer basically configures the OAuth strategy to request two tokens - an\nID token, containing the openID profile of the user, as well as an access token\nfor the provided audience (which is the API).\n\nThis is the same use case described in [this example](https://auth0.com/docs/scopes/sample-use-cases-scopes-and-claims#authenticate-a-user-and-request-standard-claims-and-custom-api-access):\n\n```\nhttps://YOUR_DOMAIN/authorize?\n  response_type=code\u0026\n  client_id=YOUR_CLIENT_ID\u0026\n  redirect_uri=https://YOUR_APP/callback\u0026\n  scope=openid%20profile%20email%20read:appointments\u0026\n  audience=YOUR_API_AUDIENCE\u0026\n  state=YOUR_STATE_VALUE\n```\n\nThe OAuth gems take care of generating and verifying the `state` parameter which\nis seen in the example request above. After successful authentication, the code\nreceived from auth0 will be [exchanged](https://auth0.com/docs/api/authentication#get-token)\nfor the tokens which we can access and store in the `callback` action of the\nauthorization controller:\n\n``` ruby\n# In controllers/oauth_controller.rb\n\ndef callback\n  data = request.env['omniauth.auth']\n  session[:id_token] = data['credentials']['id_token']\n  session[:api_access_token] = data['credentials']['token']\n  redirect_to root_path\nend\n```\n\nWe need to define a mapping between the OAuth callback and our controller action\nin `routes.rb`:\n\n```\nget  '/auth/:provider/callback', to: 'oauth#callback'\n```\n\nThis is the same callback path specified in the initializer above, as well as in the\nauth0 application configuration, as described [in this\nsection](https://github.com/npetkov/auth0_rails_api_example#creating-a-new-application).\n\nThe implementation of the OAuth controller follows the [sample Rails\nimplementation](https://auth0.com/docs/quickstart/webapp/rails) on the Auth0\nsite with some minor adaptations. Please note that both tokens are stored in the\nsession, which is not optimal as they can rapidly grow in size when defining new\nAPI permissions, for example.\n\nOne area that isn't covered in the implementation is token refresh.\n\n## Implementation notes - frontend\n\nOnce the user has been authenticated, the \"frontend\" application will load\nand perform a POST request to `/api_params`, retrieving the address\nand the access token for the API.\n\nThe API access token is kept in-memory as it can be easily retrieved from the\nbackend if needed (on page reload, for example).\n\nThe frontend implementation is deliberately kept very sparse (no stylesheets\netc.) as the focus of the project is on the authentication/authorization flow.\n## Testing\n\nI haven't implemented any tests yet so please feel free to contribute.\n\n## Contributing\n\nDon't hesitate to create issues or feature requests. Any suggestions are welcome.\n## Disclaimer\n\nI am not part of the auth0 team nor am I affiliated to auth0 in any way. I'm using auth0 for the sole purpose of\ndemonstrating a basic OAuth2 code grant flow.\n\n## License\n\nThis product is licensed under the [MIT License](https://github.com/npetkov/auth0_rails_frontend_example/blob/dev/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpetkov%2Fauth0_rails_frontend_example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnpetkov%2Fauth0_rails_frontend_example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpetkov%2Fauth0_rails_frontend_example/lists"}