2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixir × Überauth で Phoenix に OAuth2認証 を実装する

Posted at

概要

適当なサービスにログインしようとした時、以下のようなものを見たことがありませんか?

Github アカウントでconppassにログインしてみる、こういった認証を OAuth 2.0 と呼ぶそうです。

今回はこの OAuth2認証を Phoenix に実装してみたいと思います。

公開するリポジトリには記事内の手順に合わせてブランチ分けしておりますので、段階的に実装手順を沿っていけると思います。
ぜひご活用ください。

環境

以下の環境で動作確認しております。

  • macOS Sequoia 16.5
  • elixir 1.18.2-otp-27
  • erlang 27.3.2

リポジトリ

記事中のコードは以下に配置しています。

本題

ElixirPhoenix に OAuth2認証を実装するために Überauth というライブラリを使いたいと思います。

このライブラリ一本で、Gootle や Twitter などのプロバイダーごとに設定を行えば、複数のサイトの OAuth2認証 を実装することができます。

今回は Github の OAuth2認証 に絞って実装を行います。

手順

今回は次のコマンドで phxプロジェクト を生成しているものとします。

mix phx.server tutorial_ueberauth

次の手順で OAuth2認証 の実装を行います。

  1. 依存を追加
  2. 認証ファイルを作成する
  3. 設定ファイルの変更
  4. gen.authの追加
  5. Controllerの追加
  6. リンクの追加
  7. 実行

依存を追加

Überauth で Github の OAuth2認証 を実装するには、下記の依存を追加します。

  defp deps do
    [
      # 省略
      {:ueberauth, "~> 0.10"},
      {:ueberauth_github, "~> 0.8"}
    ]
  end

認証ファイルを作成する

Github に限らず OAuth2認証 を行うには認証情報が必要です。

Github の認証情報は以下のリンクで OAuth Apps を作成することで取得できます。

アクセスしたら、New oauth app を押して、作成に入りましょう。

ここで次の内容を入力しましょう。

  • Application name
    • 好きな名前をつけてください(用途がわかる名前など)
  • Homepage URL
    • ホームページのURLを指定します
    • https://localhost:4000
  • Application description
    • 説明文を記入(オプション)
  • Authorization callback URL
    • ここの [コールバック](#Controller の追加) が呼べるURLを指定する
    • http://localhost:4000/auth/github/callback

OAuthApps を作成できたら、Client IDClient secrets が生成されました。
この二つの認証情報を使用して、OAuth2認証を行います。

:exclamation:注意: Client secrets は再度表示することができないので必ずメモを取りましょう。

設定ファイルの変更

認証情報を取得できたので、config.exs の変更に入ります。

config.exs に下記の内容を追加してください。

config/config.exs
config :ueberauth, Ueberauth,
  providers: [
    github: {Ueberauth.Strategy.Github, []}
  ]

runtime.exs に下記の内容を追加してください。
runtime.exs は Phoenix に実行されます。

config/runtime.exs
config :ueberauth, Ueberauth.Strategy.Github.OAuth,
  client_id: System.get_env("GITHUB_CLIENT_ID"),
  client_secret: System.get_env("GITHUB_CLIENT_SECRET")

そして先ほどの認証情報を .env ファイルを作成し、書き込みます。

.env
GITHUB_CLIENT_ID=<ClientID>
GITHUB_CLIENT_SECRET=<Client secrets>

gen.authの追加

gen.auth を実行して、いつもの認証を追加しましょう。

mix phx.gen.auth Accounts User users    

Controller の追加

OAuth2 の設定が済んでいるので、実際に認証を行う Controller を作成しましょう。

まず router.ex に下記を追加してください。

lib/tutorial_ueberauth_web/router.ex
  # Überauth のスコープを追加
  scope "/auth", TutorialUeberauthWeb do
    pipe_through :browser

    get "/:provider", AuthController, :request
    get "/:provider/callback", AuthController, :callback
    post "/:provider/callback", AuthController, :callback
    delete "/logout", AuthController, :delete
  end

次の auth_controller.ex を追加してください。

defmodule TutorialUeberauthWeb.AuthController do
  @moduledoc """
  Auth controller responsible for handling Ueberauth responses
  """

  use TutorialUeberauthWeb, :controller

  plug Ueberauth

  alias Ueberauth.Strategy.Helpers
  alias UeberauthExample.UserFromAuth

  def request(conn, _params) do
    render(conn, "request.html", callback_url: Helpers.callback_url(conn))
  end

  def delete(conn, _params) do
    conn
    |> put_flash(:info, "You have been logged out!")
    |> clear_session()
    |> redirect(to: "/")
  end

  def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
    conn
    |> put_flash(:error, "Failed to authenticate.")
    |> redirect(to: "/")
  end

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    conn
    |> put_flash(:info, "Successfully authenticated.")
    |> put_session(:current_user, auth.uid)
    |> configure_session(renew: true)
    |> redirect(to: ~p"/")
  end
end

これは OAuth2認証 のプロバイダーで共通となる認証を行うためのページへアクセスするための Controller になります。

先ほど Github の設定にて、下記をホームページとして設定していました。

http://localhost:4000

そして auth_controller.ex を実行すると次のリンクで Github の OAuth2認証 が行われるようになります。

http://localhost:4000/auth/github

なので、上のリンクへリダイレクトするタグを作成することで、Githubアカウントでログインできるようになりました。

下記を参照

リンクの追加

先ほど gen.auth にてログインページが生成されていると思いますので、そちらのログインページに Github での認証のリンクを追加しましょう。

tutorial_ueberauth_web.user_login_live
<.link href={~p"/auth/github"} class="w-full ">Githubでログイン/登録</.link> 

実行

ここまでの作業を終えて、やっと Github の OAuth2認証 ができるようになりました。

早速動作を確認しましょう。
source を実行して .env 読み込んでから Phoenixを起動しましょう。

source .env
mix phx.server

ログインページに飛んで、先ほど追加したリンクを押しましょう。

押してみると、初回だけ次の表示が出てきます。Authorize を押しましょう。

Github での OAuth2認証 の実装完了です。

まとめ

ここまでで、Github のOAuth2 認証が実装できました。
設定を色々追加すると別のプロバイダーのものでも認証ができるようになるかと思います。
詳しくは下記を参照してください。

またログインしてみるとわかるのですが、このままではログインしても current_usernil のままなので本当に認証をしたというだけに終わってしまっています。

なので本来は、別途ユーザーを作成するといった処理の追加が必要になると思います。

最後に要点をまとめて締めたいと思います。

Überauth で OAuth2認証 を実装するには以下の手順を踏みます。

  1. Überauth の依存追加
  2. プロバイダーの認証情報を作成する(.env)
  3. Überauth の設定を追加する(config.exsruntime.exs)
  4. router.exにスコープ追加
  5. Controller を追加
  6. 環境変数を読み込ませて実行

実践で使っていくには gen_auth との組み合わせの方法がネックなので、存じておられる方は教えていただけると幸いです。

おまけ

%{ueberauth_auth: auth} の中身を確認してみた

認証成功時の ueberauth_auth の値を inspect して確認してみました。
色々省略してます。

%Ueberauth.Auth{
  uid: 12345678, # ← <ここにuid>
  provider: :github,
  info: %Ueberauth.Auth.Info{
    name: "<ここにGitHub表示名>",
    nickname: "<ここにGitHubユーザー名>",
    image: "https://avatars.githubusercontent.com/u/<ここにUID>?v=4",
    urls: %{
      html_url: "https://github.com/<ここにGitHubユーザー名>"
    }
  },
  credentials: %Ueberauth.Auth.Credentials{
    token: "<ここにアクセストークン(マスク済み)>",
    token_type: "Bearer"
  },
  # ...
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?