【Supabase】驚くほど簡単！Slack ログイン機能の実装

# はじめに
SupabaseでSlackアカウントを用いたログイン機能を実装したところ、驚くほど簡単だったのでご紹介しようと思います！

この記事は、公式ドキュメントを元に、実際の設定画面を交えながら具体的な手順をご紹介させていただきます。

- 「ドキュメントだけだとイメージが掴みにくい」
- 「UI を見ながら確実に設定したい」

というような方の助けになれば幸いです！
公式ドキュメントで十分という方は、こちらをご覧ください！

https://supabase.com/docs/guides/auth/social-login/auth-slack


余談ですが、以前 Firebase を用いた Google アカウントログインについても記事にしているので、興味があればぜひご確認ください。

https://qiita.com/fujisho1216/items/74d7d937ee3fc9390b7c

# 目次
こちらの目次で Slack ログイン機能の実装について解説していこうと思います。
1.  Supabase 上で新規プロジェクトを作成する
2.  Slack アプリを作成する
3.  Supabase に Slack の認証情報を設定する
4.  クライアントアプリにログイン処理を実装する
4.  おまけ
6.  終わりに

# 1. Supabase 上で新規プロジェクトを作成する
1. Supabase に任意のアカウントでログイン（または新規登録）します
1. 任意のプロジェクト名とパスワードを入力し、プロジェクトを作成します


![スクリーンショット 2025-06-15 14.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/e9d02652-5788-45be-8128-a77a60550c97.png)



うまくプロジェクトが作成されると、下記のようなダッシュボードが表示されます。

![スクリーンショット 2025-06-15 14.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/dc2eca08-65d6-4774-97ee-66d4858de831.png)


プロジェクトが作成できたら、早速 Slack を用いたログイン機能を実装していきます。
具体的な手順は下記です。

-   [Slack Developer Dashboard](https://api.slack.com/apps) で Slack アプリを作成し、設定する
-   Slack の `Client ID` と `Client Secret` を [Supabase プロジェクト](https://supabase.com/dashboard)に追加する
-   クライアントアプリにログインコードを追加する
    -   今回は、Nuxt3 を用いてログインコードを実装しようと思います

# 2. Slack アプリを作成する

### Slack デベロッパーアカウントにアクセス
まず、Slack の設定を行うために、[api.slack.com/apps](https://api.slack.com/apps) にアクセスします。
右上の `Create New App` をクリックして、新しいアプリを作成します。

### アプリの作成
`Create an app` というポップアップが表示されたら、 `From scratch` を選択します。
次に、アプリ名 (App Name) と開発に使用する Slack ワークスペース (Pick a workspace to develop your app in) を選択し、 `Create App` をクリックします。

![スクリーンショット 2025-06-15 16.55.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/5c55c340-3bce-4782-b7c5-952c3069a164.png)


### Client ID と Client Secret の取得
アプリが作成されると、`Basic Information` ページにリダイレクトされます。
`App Credentials` という項目に `Client ID` と `Client Secret` が表示されているので、これをコピーして安全な場所に保存しておきます。
この情報は後ほど Supabase の設定で使用します。

![スクリーンショット 2025-06-15 17.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/e9337a3c-4595-4677-9acc-8ce6b1d03724.png)



### Supabase のコールバック URL を取得する
次に、Slack から Supabase にリダイレクトするためのコールバック URL を Supabase から取得します。

1.  [Supabase のプロジェクトダッシュボード](https://supabase.com/dashboard) に戻ります
2.  左のサイドバーから `Authentication` アイコンをクリックします
3.  `Sign in / Providers` を選択します
4.  一覧の中から `Slack(OIDC)` をクリックすると、設定項目が展開されます
5.  `Callback URL` が表示されているので、`Copy` ボタンをクリックして URL をコピーします

![スクリーンショット 2025-06-15 17.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/82041dee-cf33-43f0-a96a-d4575bdb976c.png)

:::note info
補足情報
 `Slack(Deprecated)` は古い仕様のため、セキュリティの観点から、特別な理由がなければ、新しい OpenID Connect (OIDC) ベースの `Slack(OIDC)` を選択することをおすすめします。
:::

### Slack アプリにリダイレクト URL を設定する
コピーしたコールバック URL を Slack アプリに設定します。

1.  Slack のアプリ管理画面に戻ります
2.  左のサイドバーから `OAuth & Permissions` を選択します
3.  `Redirect URLs` という項目までスクロールし、 `Add New Redirect URL` をクリックします
4.  先ほど Supabase からコピーしたコールバック URL を貼り付け、 `Add` をクリックします
5.  最後に `Save URLs` をクリックして保存します

![スクリーンショット 2025-06-15 17.05.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/fd8fb38f-3d39-4c6a-ac60-44e41ba94a11.png)


# 3. Supabase に Slack の認証情報を設定する
次に、Supabase のプロジェクトに Slack アプリの認証情報を設定します

1.  Supabase のダッシュボードに戻り、再度 `Authentication` -> `Sign in / Providers` -> `Slack` を開きます
2.  `Slack enabled` のトグルをオンにします
3.  先ほど Slack アプリからコピーしておいた `Client ID` と `Client Secret` をそれぞれ入力します
4.  最後に `Save` ボタンをクリックして設定を保存します

Enabled と表示されていれば設定完了です。

![スクリーンショット 2025-06-15 17.09.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/030bbf82-fd2e-4a37-a422-d0e4a2b1f6ee.png)


# 4. クライアントアプリにログイン処理を実装する
最後に、作成したクライアントアプリ（今回は Nuxt3）に Slack でログインするためのコードを追加します。

私は、今回下記の Nuxt モジュールを使用しています。

https://supabase.nuxtjs.org/getting-started/introduction

まず、対象の Nuxt モジュールをプロジェクトに追加します。

```bash
npx nuxi@latest module add supabase
```

`nuxt.config.ts` のモジュールセクションに @nuxtjs/supabase を追加します。

```js
export default defineNuxtConfig({
  modules: ['@nuxtjs/supabase'],
})
```

`.env` に `SUPABASE_URL` と `SUPABASE_KEY` を追加します。

```js
SUPABASE_URL="<your_url>"
SUPABASE_KEY="<your_key>"
```

次に、ログインとログアウトを実行するページやコンポーネントに、以下のコードを実装します。
`signInWithOAuth` メソッドを使用することで実現できます。

:::note warn
注意
下記はサンプルコードなので、実際には、.env からリダイレクト URL を読み込む処理や、エラーハンドリング追加してください。
:::

```vue
<script setup lang="ts">
/** Supabase Client */
const client = useSupabaseClient()

// Slackでのログイン処理
const signInWithSlack = async () => {
  await client.auth.signInWithOAuth({
    provider: 'slack_oidc',
    options: {
      redirectTo: config.public.supabaseRedirectUrl,
    },
  })
}

// ログアウト処理
const signOut = async () => {
  await client.auth.signOut()
}
</script>

<template>
  <div>
    <button @click="signInWithSlack">Slack でログイン</button>
    <button @click="signOut">ログアウト</button>
  </div>
</template>

```

ログイン処理である `signInWithOAuth` メソッドは、 Supabase の認証機能を通じて Slack の認証ページにユーザーをリダイレクトさせます。
具体的なフローとしては、
1. Slack での認証が成功すると、Slack は Supabase のコールバック URL に認可コードを付与してリダイレクトします
1. バックエンドは受け取った認可コードを使い、Slack からアクセストークンと ID トークンを取得してユーザーセッション（JWT）を取得します
1. その後、options の redirectTo で指定した URL にユーザーをリダイレクトします

これが、OAuth 2.0 の認可コードフローの基本的な流れとなります。

![スクリーンショット 2025-06-15 17.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445545/178f8371-7185-4fa5-b017-0aef04cbf72f.png)


認証が成功すると、指定した redirectTo の URL にリダイレクトされ、ログイン状態となります。
ちなみに、この際、Slack アプリをインストールしたワークスペースに参加していないユーザーがログインしようとすると、Slack 側で認証エラーとなります。

また、ログアウト処理は `signOut` メソッドを呼び出すだけで実装できます。
これにより、Supabase がクライアント側で管理しているセッション情報（JWT）が破棄され、ユーザーはログアウト状態となります。

# おまけ
Supabase は、単なる認証サービスではありません。
PostgreSQL を中心として、オープンソースの Firebase 代替とも称される BaaS（Backend as a Service）プラットフォームでもあります。
今回は、おまけとして一部の機能である Database と Stroage について最後ご紹介できればと思います！
 
## Database
Supabase では、PostgreSQL を使用できます。

https://supabase.com/docs/guides/database/overview

### RLS (Row-Level Security) によるセキュリティ
Supabase では、 PostgreSQL の RLS（行単位セキュリティ）を簡単に利用することができます。
具体的には、データベースの行レベルでアクセス権限を制御する仕組みで、「ユーザーは自分自身のデータしか閲覧・編集できない」といったポリシーを SQL で定義することができます。
これにより、セキュリティが担保された状態でクライアントサイドのアプリケーションから直接データベースを操作することができます。

例えば、以下のように `auth.uid()` という Supabase が提供する関数を使い、認証済みユーザーの ID をポリシー内で参照することで、セキュリティルールを記述することができます。

```SQL

-- `profiles`テーブルにRLSを有効化
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

-- 自分のレコードのみSELECTを許可するポリシー
CREATE POLICY "Users can view their own profile."
ON profiles FOR SELECT
USING (auth.uid() = id);

-- 自分のレコードのみUPDATEを許可するポリシー
CREATE POLICY "Users can update their own profile."
ON profiles FOR UPDATE
USING (auth.uid() = id);

```

### ORMライクなクライアントライブラリ
また、まるで ORM (Object-Relational Mapper) のようにデータベースを操作できます。

下記の upsert の例では、PostgreSQL の `INSERT ... ON CONFLICT` 構文を使用しています。
`onConflict: 'uuid'` と指定することで、uuid カラムに重複があった場合は INSERT の代わりに UPDATE が実行され、レコードの作成・更新（UPSERT）を行うことができます。

```js

/** Supabase Client */
const client = useSupabaseClient()

await useAsyncData(
  `user-upsert-${userId}`,
  async () => {
    await client.from('users').upsert(
      {
        uuid: userId,
        email: email,
        name: slackName,
        slack_member_id: memberId,
        slack_profile_image: profileImageUrl,
      },
      { onConflict: 'uuid' },
    )
  }
)

  ```

## Storage
次にご紹介するのは、画像や動画、ドキュメントといった静的ファイルを保存するためのオブジェクトストレージ機能です。
特長として、先述の Database（RLS）と連携することができます。

例えば、
「 avatars バケット内のファイルは、ファイルパスに含まれるユーザー ID と、現在ログインしているユーザーの ID が一致する場合のみアップロード・更新を許可する」
といったアクセスポリシーを、SQL で定義できます。

### 署名付きURL (Signed URLs)
具体例として、下記の `createSignedUrls` は、署名付きURLを生成するメソッドです。
これは、プライベート設定のバケットに保存されたファイルに対し、有効期限付きの一時的なアクセス権を付与するための URL で、本来アクセス権のないユーザーにも安全にファイルを共有することができます。

```js
/** Supabase Client */
const client = useSupabaseClient()

const { data: memoryPhotos } = await useAsyncData(
  'user-memory-photos',
  async () => {
    const response = await client.storage
      .from('memory-image')
      .createSignedUrls(fileNames, 60 * 60)
    
    return response.data
  }
)
```

# 終わりに
以上で、Supabase と Slack を用いた認証機能の実装は完了です！
見ていただいた通り、数ステップで簡単に slack ログインを導入できました。
最後に Database や Storage についてご紹介しましたが、それ以外にも、Edge Functions（Database の変更をトリガーにしたり、外部サービスの Webhook を受け取ることのできるサーバーレス関数）もあったりします。
Supabase はドキュメントも豊富で特に躓くことなく実装することができると思うので、手軽に認証だったりを試したい方などぜひ皆さんも試してみてください！