{"id":13436041,"url":"https://github.com/ueberauth/oauth2","last_synced_at":"2025-12-12T00:31:08.066Z","repository":{"id":17742849,"uuid":"20585853","full_name":"ueberauth/oauth2","owner":"ueberauth","description":"An Elixir OAuth 2.0 Client Library","archived":false,"fork":false,"pushed_at":"2024-07-25T13:39:28.000Z","size":320,"stargazers_count":761,"open_issues_count":1,"forks_count":138,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-16T08:05:52.195Z","etag":null,"topics":["elixir","http","oauth2"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/ueberauth.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-07T04:55:22.000Z","updated_at":"2025-04-24T11:21:13.000Z","dependencies_parsed_at":"2024-02-05T02:38:51.906Z","dependency_job_id":"cd07497a-cdab-4e40-a60a-080e00a57c4f","html_url":"https://github.com/ueberauth/oauth2","commit_stats":{"total_commits":275,"total_committers":49,"mean_commits":5.612244897959184,"dds":"0.31999999999999995","last_synced_commit":"7589795f0ef30bc63da7789b924f67e82471c0c4"},"previous_names":["scrogson/oauth2"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ueberauth%2Foauth2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ueberauth%2Foauth2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ueberauth%2Foauth2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ueberauth%2Foauth2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ueberauth","download_url":"https://codeload.github.com/ueberauth/oauth2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493378,"owners_count":22080126,"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":["elixir","http","oauth2"],"created_at":"2024-07-31T03:00:42.721Z","updated_at":"2025-12-12T00:31:08.030Z","avatar_url":"https://github.com/ueberauth.png","language":"Elixir","readme":"# OAuth2 (Client)\n\n[![Build Status](https://github.com/ueberauth/oauth2/actions/workflows/ci.yml/badge.svg)](https://github.com/ueberauth/oauth2/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/scrogson/oauth2/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/scrogson/oauth2?branch=master)\n[![Module Version](https://img.shields.io/hexpm/v/oauth2.svg)](https://hex.pm/packages/oauth2)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/oauth2/)\n[![Total Download](https://img.shields.io/hexpm/dt/oauth2.svg)](https://hex.pm/packages/oauth2)\n[![License](https://img.shields.io/hexpm/l/oauth2.svg)](https://github.com/scrogson/oauth2/blob/master/LICENSE)\n[![Last Updated](https://img.shields.io/github/last-commit/scrogson/oauth2.svg)](https://github.com/scrogson/oauth2/commits/master)\n\nAn Elixir [OAuth](https://en.wikipedia.org/wiki/OAuth) 2.0 Client Library.\n\n## Install\n\n```elixir\n# mix.exs\n\ndefp deps do\n  # Add the dependency\n  [\n    {:oauth2, \"~\u003e 2.0\"},\n    {:hackney, \"~\u003e 1.18\"} # depending on what tesla adapter you use\n  ]\nend\n```\n\n## Configure a serializer\n\nThis library can be configured to handle encoding and decoding requests and\nresponses automatically based on the `accept` and/or `content-type` headers.\n\nIf you need to handle various MIME types, you can simply register serializers like so:\n\n```elixir\nOAuth2.Client.put_serializer(client, \"application/vnd.api+json\", Jason)\nOAuth2.Client.put_serializer(client, \"application/xml\", MyApp.Parsers.XML)\n```\n\nThe modules are expected to export `encode!/1` and `decode!/1`.\n\n```elixir\ndefmodule MyApp.Parsers.XML do\n  def encode!(data), do: # ...\n  def decode!(binary), do: # ...\nend\n```\n\nPlease see the documentation for [OAuth2.Serializer](https://hexdocs.pm/oauth2/OAuth2.Serializer.html)\nfor more details.\n\n## Configure a http client\n\nThe http client library used is [tesla](https://github.com/elixir-tesla/tesla), the default adapter is\nHttpc, since it comes out of the box with every Erlang instance but you can easily change it to something\nbetter.\nYou can configure another adaptor like this:\n\n```elixir\nconfig :oauth2, adapter: Tesla.Adapter.Mint\n```\n\nYou can also add your own tesla middleware:\n\n```elixir\nconfig :oauth2, middleware: [\n  Tesla.Middleware.Retry,\n  {Tesla.Middleware.Fuse, name: :example}\n]\n```\n\n## Debug mode\n\nSometimes it's handy to see what's coming back from the response when getting\na token. You can configure OAuth2 to output the response like so:\n\n```elixir\nconfig :oauth2, debug: true\n```\n\n## Usage\n\nCurrent implemented strategies:\n\n- Authorization Code\n- Password\n- Client Credentials\n\n### Authorization Code Flow (AuthCode Strategy)\n\n```elixir\n# Initialize a client with client_id, client_secret, site, and redirect_uri.\n# The strategy option is optional as it defaults to `OAuth2.Strategy.AuthCode`.\n\nclient = OAuth2.Client.new([\n  strategy: OAuth2.Strategy.AuthCode, #default\n  client_id: \"client_id\",\n  client_secret: \"abc123\",\n  site: \"https://auth.example.com\",\n  redirect_uri: \"https://example.com/auth/callback\"\n])\n\n# Generate the authorization URL and redirect the user to the provider.\nOAuth2.Client.authorize_url!(client)\n# =\u003e \"https://auth.example.com/oauth/authorize?client_id=client_id\u0026redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Fcallback\u0026response_type=code\"\n\n# Use the authorization code returned from the provider to obtain an access token.\nclient = OAuth2.Client.get_token!(client, code: \"someauthcode\")\n\n# Use the access token to make a request for resources\nresource = OAuth2.Client.get!(client, \"/api/resource\").body\n```\n\n### Client Credentials Flow\n\nGetting an initial access token:\n\n```elixir\n# Initializing a client with the strategy `OAuth2.Strategy.ClientCredentials`\n\nclient = OAuth2.Client.new([\n  strategy: OAuth2.Strategy.ClientCredentials,\n  client_id: \"client_id\",\n  client_secret: \"abc123\",\n  site: \"https://auth.example.com\"\n])\n\n# Request a token from with the newly created client\n# Token will be stored inside the `%OAuth2.Client{}` struct (client.token)\nclient = OAuth2.Client.get_token!(client)\n\n# client.token contains the `%OAuth2.AccessToken{}` struct\n\n# raw access token\naccess_token = client.token.access_token\n```\n\nRefreshing an access token:\n\n```elixir\n# raw refresh token - use a client with `OAuth2.Strategy.Refresh` for refreshing the token\nrefresh_token = client.token.refresh_token\n\nrefresh_client = OAuth2.Client.new([\n  strategy: OAuth2.Strategy.Refresh,\n  client_id: \"client_id\",\n  client_secret: \"abc123\",\n  site: \"https://auth.example.com\",\n  params: %{\"refresh_token\" =\u003e refresh_token}\n])\n\n# refresh_client.token contains the `%OAuth2.AccessToken{}` struct again\nrefresh_client = OAuth2.Client.get_token!(refresh_client)\n```\n\n## Write Your Own Strategy\n\nHere's an example strategy for GitHub:\n\n```elixir\ndefmodule GitHub do\n  use OAuth2.Strategy\n\n  # Public API\n\n  def client do\n    OAuth2.Client.new([\n      strategy: __MODULE__,\n      client_id: System.get_env(\"GITHUB_CLIENT_ID\"),\n      client_secret: System.get_env(\"GITHUB_CLIENT_SECRET\"),\n      redirect_uri: \"http://myapp.com/auth/callback\",\n      site: \"https://api.github.com\",\n      authorize_url: \"https://github.com/login/oauth/authorize\",\n      token_url: \"https://github.com/login/oauth/access_token\"\n    ])\n    |\u003e OAuth2.Client.put_serializer(\"application/json\", Jason)\n  end\n\n  def authorize_url! do\n    OAuth2.Client.authorize_url!(client(), scope: \"user,public_repo\")\n  end\n\n  # you can pass options to the underlying http library via `opts` parameter\n  def get_token!(params \\\\ [], headers \\\\ [], opts \\\\ []) do\n    OAuth2.Client.get_token!(client(), params, headers, opts)\n  end\n\n  # Strategy Callbacks\n\n  def authorize_url(client, params) do\n    OAuth2.Strategy.AuthCode.authorize_url(client, params)\n  end\n\n  def get_token(client, params, headers) do\n    client\n    |\u003e put_header(\"accept\", \"application/json\")\n    |\u003e OAuth2.Strategy.AuthCode.get_token(params, headers)\n  end\nend\n```\n\nHere's how you'd use the example GitHub strategy:\n\nGenerate the authorize URL and redirect the client for authorization.\n\n```elixir\nGitHub.authorize_url!\n```\n\nCapture the `code` in your callback route on your server and use it to obtain an access token.\n\n```elixir\nclient = GitHub.get_token!(code: code)\n```\n\nUse the access token to access desired resources.\n\n```elixir\nuser = OAuth2.Client.get!(client, \"/user\").body\n\n# Or\ncase OAuth2.Client.get(client, \"/user\") do\n  {:ok, %OAuth2.Response{body: user}} -\u003e\n    user\n  {:error, %OAuth2.Response{status_code: 401, body: body}} -\u003e\n    Logger.error(\"Unauthorized token\")\n  {:error, %OAuth2.Error{reason: reason}} -\u003e\n    Logger.error(\"Error: #{inspect reason}\")\nend\n```\n\n## Examples\n\n- [Authenticate with Github (OAuth2/Phoenix)](https://github.com/scrogson/oauth2_example)\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Sonny Scroggin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","funding_links":[],"categories":["Elixir"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fueberauth%2Foauth2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fueberauth%2Foauth2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fueberauth%2Foauth2/lists"}