# useOAuth & usePasskey

`DidConnect` コンポーネントと `useConnect` フックは、すべての認証方法に対応する包括的なビルド済み UI を提供しますが、カスタムの認証フローを構築する必要がある場合もあります。`useOAuth` フックと `usePasskey` フックは、ソーシャルログイン (OAuth) とパスワードレス認証 (Passkey) の基盤となるロジックへの直接アクセスを提供します。

これらのフックは、オーダーメイドのユーザーエクスペリエンスを作成するための強力なツールです。これらは、それぞれのコンテキストプロバイダーである `OAuthProvider` と `PasskeyProvider` に依存しており、これらは通常、メインの `SessionProvider` 内に含まれています。セッション管理の詳細については、[SessionProvider ドキュメント](./core-components-session-provider.md) を参照してください。

## useOAuth

`useOAuth` フックは、サードパーティのソーシャルログインフローを処理するための関数と状態を提供します。

### インポート

```javascript icon=logos:javascript
import { useOAuth } from '@arcblock/did-connect-react/lib/OAuth';
```

### 戻り値

このフックは、以下のプロパティとメソッドを含むオブジェクトを返します。

<x-field-group>
  <x-field data-name="loginOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>指定された OAuth プロバイダーでログインフローを開始します。ユーザー認証のためのポップアップを開き、ログイン結果で解決されるプロミスを返します。</x-field-desc>
  </x-field>
  <x-field data-name="bindOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>現在ログインしているユーザーのセッションに新しい OAuth アカウントをバインドします。</x-field-desc>
  </x-field>
  <x-field data-name="unbindOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>現在のユーザーのセッションから OAuth アカウントのバインドを解除します。</x-field-desc>
  </x-field>
  <x-field data-name="getOAuthConfigList" data-type="function" data-required="true">
    <x-field-desc markdown>Blocklet 設定から有効で設定済みの OAuth プロバイダーのリストを取得します。プロバイダー設定オブジェクトの配列に解決されるプロミスを返します。</x-field-desc>
  </x-field>
  <x-field data-name="switchOAuthPassport" data-type="function" data-required="true">
    <x-field-desc markdown>同じIDの異なる接続済みアカウント (パスポート) 間で切り替えるフローを開始します。</x-field-desc>
  </x-field>
  <x-field data-name="bindAuthLoading" data-type="boolean" data-required="true">
    <x-field-desc markdown>`bindOAuth` 操作が進行中に `true` となるブール値フラグ。</x-field-desc>
  </x-field>
  <x-field data-name="unbindAuthLoading" data-type="boolean" data-required="true">
    <x-field-desc markdown>`unbindOAuth` 操作が進行中に `true` となるブール値フラグ。</x-field-desc>
  </x-field>
  <x-field data-name="oauthState" data-type="object" data-required="true">
    <x-field-desc markdown>認証プロセスのリアルタイムステータスを含むオブジェクト。</x-field-desc>
    <x-field data-name="loading" data-type="boolean" data-desc="OAuth 操作が進行中の場合は True。"></x-field>
    <x-field data-name="error" data-type="string" data-desc="操作が失敗した場合のエラーメッセージを含みます。"></x-field>
    <x-field data-name="status" data-type="string" data-desc="フローの現在のステータス (例: 'scanned', 'succeed', 'error')。"></x-field>
  </x-field>
</x-field-group>

### 使用例

以下は、カスタムソーシャルログインコンポーネントを構築する方法の例です。

```jsx CustomSocialLogin.jsx icon=logos:react
import React, { useEffect, useState } from 'react';
import { useOAuth } from '@arcblock/did-connect-react/lib/OAuth';
import { useSession } from '@arcblock/did-connect-react/lib/Session';

export default function CustomSocialLogin() {
  const { loginOAuth, getOAuthConfigList } = useOAuth();
  const { session } = useSession();
  const [providers, setProviders] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    // コンポーネントがマウントされたときに、利用可能な OAuth プロバイダーのリストを取得します
    getOAuthConfigList().then(setProviders).catch(console.error);
  }, [getOAuthConfigList]);

  const handleLogin = async (provider) => {
    setLoading(true);
    setError('');
    try {
      const result = await loginOAuth({ provider: provider.provider });
      // ログインが成功すると、セッションは SessionProvider によって自動的に更新されます。
      console.log('Login successful:', result);
      // ここでセッションを更新したり、ユーザーをリダイレクトしたりすることができます。
    } catch (err) {
      setError(err.message);
      console.error('Login failed:', err);
    } finally {
      setLoading(false);
    }
  };

  if (session.user) {
    return <div>You are already logged in as {session.user.name}.</div>;
  }

  if (providers.length === 0) {
    return <div>No social login methods configured.</div>;
  }

  return (
    <div>
      <h3>Login with Social Media</h3>
      {providers.map((p) => (
        <button key={p.provider} onClick={() => handleLogin(p)} disabled={loading}>
          {loading ? 'Logging in...' : `Login with ${p.provider}`}
        </button>
      ))}
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

## usePasskey

`usePasskey` フックは、WebAuthn (Passkeys) を使用したパスワードレス認証を処理するための関数と状態を提供します。

### インポート

```javascript icon=logos:javascript
import { usePasskey } from '@arcblock/did-connect-react/lib/Passkey';
```

### 戻り値

このフックは、以下のプロパティとメソッドを含むオブジェクトを返します。

<x-field-group>
  <x-field data-name="loginPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>既存の Passkey を使用してログインフローを開始します。ブラウザのネイティブ WebAuthn 認証プロンプトをトリガーします。</x-field-desc>
  </x-field>
  <x-field data-name="connectPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>新しい Passkey を作成し、現在のユーザーのセッションにバインドするフローを開始します。</x-field-desc>
  </x-field>
  <x-field data-name="disconnectPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>検証が成功した後、現在のユーザーのセッションから Passkey のバインドを解除します。</x-field-desc>
  </x-field>
  <x-field data-name="switchPassport" data-type="function" data-required="true">
    <x-field-desc markdown>異なる接続済みアカウント (パスポート) 間で切り替えるフローを開始します。</x-field-desc>
  </x-field>
  <x-field data-name="connecting" data-type="boolean" data-required="true">
    <x-field-desc markdown>`connectPasskey` 操作が進行中に `true` となるブール値フラグ。</x-field-desc>
  </x-field>
  <x-field data-name="disconnecting" data-type="boolean" data-required="true">
    <x-field-desc markdown>`disconnectPasskey` 操作が進行中に `true` となるブール値フラグ。</x-field-desc>
  </x-field>
  <x-field data-name="passkeyState" data-type="object" data-required="true">
    <x-field-desc markdown>Passkey 操作のリアルタイムステータスを含むオブジェクト。</x-field-desc>
    <x-field data-name="loading" data-type="boolean" data-desc="Passkey 操作が進行中の場合は True。"></x-field>
    <x-field data-name="creating" data-type="boolean" data-desc="Passkey 作成フェーズ中は True。"></x-field>
    <x-field data-name="verifying" data-type="boolean" data-desc="Passkey 検証フェーズ中は True。"></x-field>
    <x-field data-name="error" data-type="string" data-desc="操作が失敗した場合のエラーメッセージを含みます。"></x-field>
    <x-field data-name="status" data-type="string" data-desc="フローの現在のステータス (例: 'scanned', 'succeed', 'error')。"></x-field>
  </x-field>
</x-field-group>

### 使用例

以下は、「Passkeyでログイン」ボタンを作成する方法の例です。

```jsx PasskeyLoginButton.jsx icon=logos:react
import React, { useState } from 'react';
import { usePasskey } from '@arcblock/did-connect-react/lib/Passkey';

export default function PasskeyLoginButton() {
  const { loginPasskey, passkeyState } = usePasskey();
  const [error, setError] = useState('');

  const handleLogin = async () => {
    setError('');
    try {
      const result = await loginPasskey();
      console.log('Passkey login successful:', result);
      // セッションは SessionProvider によって自動的に更新されます。
    } catch (err) {
      setError(err.message);
      console.error('Passkey login failed:', err);
    }
  };

  return (
    <div>
      <button onClick={handleLogin} disabled={passkeyState.loading}>
        {passkeyState.loading ? 'Verifying...' : 'Login with Passkey'}
      </button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

これらのフックは、DID Connect の強力な認証機能を、完全にカスタムな UI でアプリケーションの任意の部分に統合する柔軟性を提供します。ビルド済みの `DidConnect` モーダルをプログラムで制御する方法については、[useConnect フックのドキュメント](./hooks-use-connect.md) に進んでください。