Skip to content

Commit 214f84a

Browse files
committed
Add facebook
1 parent c799bd6 commit 214f84a

File tree

6 files changed

+82
-11
lines changed

6 files changed

+82
-11
lines changed

config/config.exs

-1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,3 @@ config :phoenix, :generators,
3131
# Import environment specific config. This must remain at the bottom
3232
# of this file so it overrides the configuration defined above.
3333
import_config "#{Mix.env}.exs"
34-

config/dev.exs

+4
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ config :oauth2_example, Google,
5151
client_secret: System.get_env("GOOGLE_CLIENT_SECRET"),
5252
redirect_uri: System.get_env("GOOGLE_REDIRECT_URI")
5353

54+
config :oauth2_example, Facebook,
55+
client_id: System.get_env("FACEBOOK_CLIENT_ID"),
56+
client_secret: System.get_env("FACEBOOK_CLIENT_SECRET"),
57+
redirect_uri: System.get_env("FACEBOOK_REDIRECT_URI")

web/controllers/auth_controller.ex

+26-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ defmodule OAuth2Example.AuthController do
99
redirect conn, external: authorize_url!(provider)
1010
end
1111

12+
def delete(conn, _params) do
13+
conn
14+
|> put_flash(:info, "You have been logged out!")
15+
|> configure_session(drop: true)
16+
|> redirect(to: "/")
17+
end
18+
1219
@doc """
1320
This action is reached via `/auth/:provider/callback` is the the callback URL that
1421
the OAuth2 provider will redirect the user back to with a `code` that will
@@ -20,7 +27,7 @@ defmodule OAuth2Example.AuthController do
2027
token = get_token!(provider, code)
2128

2229
# Request the user's data with the access token
23-
user = get_user!(provider, token).body
30+
user = get_user!(provider, token)
2431

2532
# Store the user in the session under `:current_user` and redirect to /.
2633
# In most cases, we'd probably just store the user's ID that can be used
@@ -35,15 +42,26 @@ defmodule OAuth2Example.AuthController do
3542
|> redirect(to: "/")
3643
end
3744

38-
defp authorize_url!("github"), do: GitHub.authorize_url!
39-
defp authorize_url!("google"), do: Google.authorize_url!(scope: "https://www.googleapis.com/auth/userinfo.email")
45+
defp authorize_url!("github"), do: GitHub.authorize_url!
46+
defp authorize_url!("google"), do: Google.authorize_url!(scope: "https://www.googleapis.com/auth/userinfo.email")
47+
defp authorize_url!("facebook"), do: Facebook.authorize_url!(scope: "user_photos")
4048
defp authorize_url!(_), do: raise "No matching provider available"
4149

42-
defp get_token!("github", code), do: GitHub.get_token!(code: code)
43-
defp get_token!("google", code), do: Google.get_token!(code: code)
50+
defp get_token!("github", code), do: GitHub.get_token!(code: code)
51+
defp get_token!("google", code), do: Google.get_token!(code: code)
52+
defp get_token!("facebook", code), do: Facebook.get_token!(code: code)
4453
defp get_token!(_, _), do: raise "No matching provider available"
4554

46-
defp get_user!("github", token), do: OAuth2.AccessToken.get!(token, "/user")
47-
defp get_user!("google", token), do: OAuth2.AccessToken.get!(token, "https://www.googleapis.com/plus/v1/people/me/openIdConnect")
55+
defp get_user!("github", token) do
56+
{:ok, %{body: user}} = OAuth2.AccessToken.get(token, "/user")
57+
%{name: user["name"], avatar: user["avatar_url"]}
58+
end
59+
defp get_user!("google", token) do
60+
{:ok, %{body: user}} = OAuth2.AccessToken.get(token, "https://www.googleapis.com/plus/v1/people/me/openIdConnect")
61+
%{name: user["name"], avatar: user["picture"]}
62+
end
63+
defp get_user!("facebook", token) do
64+
{:ok, %{body: user}} = OAuth2.AccessToken.get(token, "/me", fields: "id,name")
65+
%{name: user["name"], avatar: "https://graph.facebook.com/#{user["id"]}/picture"}
66+
end
4867
end
49-

web/oauth/facebook.ex

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
defmodule Facebook do
2+
@moduledoc """
3+
An OAuth2 strategy for Facebook.
4+
"""
5+
use OAuth2.Strategy
6+
7+
alias OAuth2.Strategy.AuthCode
8+
9+
defp config do
10+
[strategy: Facebook,
11+
site: "https://graph.facebook.com",
12+
authorize_url: "https://www.facebook.com/dialog/oauth",
13+
token_url: "/oauth/access_token"]
14+
end
15+
16+
# Public API
17+
18+
def client do
19+
Application.get_env(:oauth2_example, Facebook)
20+
|> Keyword.merge(config())
21+
|> OAuth2.Client.new()
22+
end
23+
24+
def authorize_url!(params \\ []) do
25+
OAuth2.Client.authorize_url!(client(), params)
26+
end
27+
28+
def get_token!(params \\ [], headers \\ []) do
29+
OAuth2.Client.get_token!(client(), params)
30+
end
31+
32+
# Strategy Callbacks
33+
34+
def authorize_url(client, params) do
35+
AuthCode.authorize_url(client, params)
36+
end
37+
38+
def get_token(client, params, headers) do
39+
client
40+
|> put_header("Accept", "application/json")
41+
|> AuthCode.get_token(params, headers)
42+
end
43+
end

web/router.ex

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ defmodule OAuth2Example.Router do
2121

2222
get "/:provider", AuthController, :index
2323
get "/:provider/callback", AuthController, :callback
24+
delete "/logout", AuthController, :delete
2425
end
2526

2627
# Fetch the current user from the session and add it to `conn.assigns`. This

web/templates/layout/app.html.eex

+8-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@
4444
<iframe src="https://ghbtns.com/github-btn.html?user=scrogson&repo=oauth2_example&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="160px" height="30px"></iframe>
4545

4646
<%= if @current_user do %>
47-
<h2>Welcome, <%= @current_user["name"] %>!</h2>
48-
<img src="<%= @current_user["avatar_url"] || @current_user["picture"] %>" class="img-circle"/>
47+
<h2>Welcome, <%= @current_user.name %>!</h2>
48+
<img src="<%= @current_user.avatar %>" class="img-circle"/>
49+
<%= link "Logout", to: auth_path(@conn, :delete), method: :delete, class: "btn btn-danger" %>
4950
<% else %>
5051
<br>
5152
<br>
@@ -59,6 +60,11 @@
5960
<i class="fa fa-github"></i>
6061
Sign in with GitHub
6162
</a>
63+
64+
<a class="btn btn-primary btn-lg" href="<%= auth_path @conn, :index, "facebook" %>">
65+
<i class="fa fa-facebook"></i>
66+
Sign in with Facebook
67+
</a>
6268
<% end %>
6369
</div>
6470

0 commit comments

Comments
 (0)