Awesome
OAuth2 GitHub
A GitHub OAuth2 Provider for Elixir
OAuth2 GitHub is convenience library built on top of oauth2
. It adds GitHub specific functions to interact with GitHub endpoints using OAuth2.
Installation
# mix.exs
def application do
# Add the application to your list of applications.
# This will ensure that it will be included in a release.
[applications: [:logger, :oauth2_github]]
end
defp deps do
# Add the dependency
[{:oauth2_github, "~> 0.1"}]
end
Authenticating a User
For an easy-to-use, end-to-end solution enabling users to log in with GitHub see
ueberauth/ueberauth_github
One common use-case is authenticating a user's identify. The get_user!
function wraps two actions into one - exchanging the callback code for a short-lived access token and using the access token to return user data:
alias OAuth2.Provider.GitHub
GitHub.get_user!([code: "<callback-code>"], [redirect_uri: "..."])
When successful, it returns the user data:
{:ok, %{"collaborators" => 0, "two_factor_authentication" => true, "company" => nil, "bio" => nil, "following" => 0, "followers_url" => "https://api.github.com/users/example/followers", "public_gists" => 0, "id" => 1, "avatar_url" => "https://avatars1.githubusercontent.com/u/1?v=4", "events_url" => "https://api.github.com/users/example/events{/privacy}", "starred_url" => "https://api.github.com/users/example/starred{/owner}{/repo}", "emails" => [%{"email" => "chris.laskey@gmail.com", "primary" => true, "verified" => true, "visibility" => "public"}, %{"email" => "1@example.com", "primary" => false, "verified" => true, "visibility" => nil}, %{"email" => "2@example.com", "primary" => false, "verified" => true, "visibility" => nil}, %{"email" => "3@example.com", "primary" => false, "verified" => false, "visibility" => nil}], "private_gists" => 0, "blog" => "http://example.com", "subscriptions_url" => "https://api.github.com/users/example/subscriptions", "type" => "User", "disk_usage" => 517040, "site_admin" => false, "owned_private_repos" => 0, "public_repos" => 75, "location" => "Moon", "hireable" => nil, "created_at" => "2016-10-30T22:30:53Z", "name" => "John Smith", "organizations_url" => "https://api.github.com/users/example/orgs", "gists_url" => "https://api.github.com/users/example/gists{/gist_id}", "following_url" => "https://api.github.com/users/example/following{/other_user}", "url" => "https://api.github.com/users/example", "email" => "contact@example.com", "login" => "example", "html_url" => "https://github.com/example", "gravatar_id" => "", "received_events_url" => "https://api.github.com/users/example/received_events", "repos_url" => "https://api.github.com/users/example/repos", "plan" => %{"collaborators" => 0, "name" => "free", "private_repos" => 0, "space" => 32976562499}, "followers" => 0, "updated_at" => "2017-01-03T01:00:40Z", "total_private_repos" => 0}}
Returning an Access Token
A valid access token can be used to make multiple requests to GitHub. The callback code can be exchanged for an access token using get_token!
:
alias OAuth2.Provider.GitHub
client = GitHub.get_token!([code: "<callback-code>"], [redirect_uri: "..."])
When successful, it will return a valid OAuth2.Client
:
%OAuth2.Client{authorize_url: "https://github.com/login/oauth/authorize", client_id: "<...>", client_secret: "<...>", headers: [], params: %{}, redirect_uri: "http://localhost:3000/login/github/callback", ref: nil, request_opts: [], site: "https://api.github.com", strategy: OAuth2.Provider.GitHub, token: %OAuth2.AccessToken{access_token: "38aac97adc9722c62272bf521a38e4f0cd7423fa", expires_at: nil, other_params: %{"scope" => "user"}, refresh_token: nil, token_type: "Bearer"}, token_method: :post, token_url: "https://github.com/login/oauth/access_token"}
Note: The access token is kept under the client's token
key.
Using a Valid Client
A valid client with an access token can then be passed into endpoint specific functions. For example, to return user data using a client
with a valid access token:
alias OAuth2.Provider.GitHub
{:ok, user} = GitHub.get_user(client)
When successful, it will return the same user information:
%{"collaborators" => 0, "two_factor_authentication" => true, "company" => nil, "bio" => nil, "following" => 0, "followers_url" => "https://api.github.com/users/example/followers", "public_gists" => 0, "id" => 1, "avatar_url" => "https://avatars1.githubusercontent.com/u/1?v=4", "events_url" => "https://api.github.com/users/example/events{/privacy}", "starred_url" => "https://api.github.com/users/example/starred{/owner}{/repo}", "emails" => [%{"email" => "chris.laskey@gmail.com", "primary" => true, "verified" => true, "visibility" => "public"}, %{"email" => "1@example.com", "primary" => false, "verified" => true, "visibility" => nil}, %{"email" => "2@example.com", "primary" => false, "verified" => true, "visibility" => nil}, %{"email" => "3@example.com", "primary" => false, "verified" => false, "visibility" => nil}], "private_gists" => 0, "blog" => "http://example.com", "subscriptions_url" => "https://api.github.com/users/example/subscriptions", "type" => "User", "disk_usage" => 517040, "site_admin" => false, "owned_private_repos" => 0, "public_repos" => 75, "location" => "Moon", "hireable" => nil, "created_at" => "2016-10-30T22:30:53Z", "name" => "John Smith", "organizations_url" => "https://api.github.com/users/example/orgs", "gists_url" => "https://api.github.com/users/example/gists{/gist_id}", "following_url" => "https://api.github.com/users/example/following{/other_user}", "url" => "https://api.github.com/users/example", "email" => "contact@example.com", "login" => "example", "html_url" => "https://github.com/example", "gravatar_id" => "", "received_events_url" => "https://api.github.com/users/example/received_events", "repos_url" => "https://api.github.com/users/example/repos", "plan" => %{"collaborators" => 0, "name" => "free", "private_repos" => 0, "space" => 32976562499}, "followers" => 0, "updated_at" => "2017-01-03T01:00:40Z", "total_private_repos" => 0}