この記事では、FlutterでVRChat APIを叩いて情報を取得する方法を紹介します。
具体的には、以下を実装します:
ユーザー名/メールアドレスとパスワードを使用して、認証トークンを取得します。
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:vrchat_matching/model/src/vrchat_user.dart';
// VRChat APIとの通信を管理するクラス
class VrChatApi {
  // VRChat APIに送信するUser-Agentの設定
  final userAgent = 'application/1.00 user@example.com';
  // 認証トークンを取得するメソッド
  Future<Map<String, dynamic>> getAuthToken({
    required String usernameOrEmail, // ユーザー名またはメールアドレス
    required String password,        // パスワード
  }) async {
    var apiKey = '';
    // VRChat APIのクライアントAPIキーを取得
    final response = await http.get(
      Uri.parse('https://api.vrchat.cloud/api/1/config'),
      headers: {'User-Agent': userAgent},
    );
    if (response.statusCode == 200) {
      // レスポンスからAPIキーを抽出
      var data = jsonDecode(response.body);
      apiKey = data['clientApiKey'] ?? '';
    } else {
      print('APIキーの取得に失敗: ${response.statusCode}');
    }
    // ベーシック認証ヘッダーを作成
    final authHeader =
        'Basic ${base64Encode(utf8.encode('$usernameOrEmail:$password'))}';
    // リクエストに必要なヘッダーを準備
    final headers = {
      'Authorization': authHeader, // 認証情報
      'User-Agent': userAgent,     
    };
    // 認証エンドポイントにリクエストを送信
    final url = Uri.parse('https://api.vrchat.cloud/api/1/auth/user');
    final responseData = await http.get(url, headers: headers);
    // レスポンスが成功の場合
    if (responseData.statusCode == 200) {
      // Set-Cookieヘッダーから認証トークンを抽出
      var cookies = responseData.headers['set-cookie'];
      if (cookies != null) {
        var tokenMatch = RegExp(r'auth=([^;]+)').firstMatch(cookies);
        if (tokenMatch != null) {
          final authToken = tokenMatch.group(1);
          // 認証トークンとAPIキーを返す
          return {
            'authToken': authToken,    // 認証トークン
            'apiKey': apiKey,          // APIキー
          };
        }
      }
    } else {
      // 認証が失敗した場合のログ
      print('認証失敗: ${responseData.statusCode}');
    }
    return {};
  }
}
取得した認証トークンとAPIキーとメールで送られてくるワンタイムコードを使用して、2段階認証します。
  Future<bool> activeToken({
    required String oneTimeCode,
    required String authToken,
    required String apiKey,
  }) async {
    final url = Uri.parse(
        'https://api.vrchat.cloud/api/1/auth/twofactorauth/totp/verify');
    final headers = {
      'User-Agent': userAgent,
      'Cookie': 'auth=$authToken', // 認証トークンをクッキーとして送信
    };
    final body = {
      'code': oneTimeCode, //ワンタイムコード
      'apiKey': apiKey,    // 取得したAPIキー
    };
    final response = await http.post(url, headers: headers, body: body);
    if (response.statusCode == 200) {
      return true;
    } else {
      print('2FA認証失敗: ${response.statusCode}');
      return false;
    }
  }
認証トークンを使用してユーザー情報を取得します。
  Future<void> getUserData({required String authToken}) async {
    final url = Uri.parse('https://api.vrchat.cloud/api/1/auth/user');
    final headers = {
      'User-Agent': userAgent,
      'Cookie': 'auth=$authToken',
    };
    try {
      final response = await http.get(url, headers: headers);
      if (response.statusCode == 200) {
        printLongText(response.body);
        final data = jsonDecode(response.body);
        
      } else {
        print('Failed to fetch user info: ${response.statusCode}');
        printLongText(response.body);
      }
    } catch (e) {
      print('Error: $e');
    }
  }
可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More