56 lines
2.0 KiB
Dart
56 lines
2.0 KiB
Dart
import 'dart:convert';
|
||
import 'package:crypto/crypto.dart';
|
||
import 'package:device_info_plus/device_info_plus.dart';
|
||
import 'package:flutter/foundation.dart';
|
||
|
||
/// デバイスID取得サービス
|
||
/// レート制限のためのデバイス識別に使用
|
||
class DeviceService {
|
||
static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
|
||
static String? _cachedDeviceId;
|
||
|
||
/// デバイス固有のIDを取得(SHA256ハッシュ化)
|
||
static Future<String> getDeviceId() async {
|
||
// キャッシュがあれば返す
|
||
if (_cachedDeviceId != null) {
|
||
return _cachedDeviceId!;
|
||
}
|
||
|
||
try {
|
||
String deviceIdentifier;
|
||
|
||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||
final androidInfo = await _deviceInfo.androidInfo;
|
||
// Android IDを使用(アプリ再インストールでも同じIDを維持)
|
||
deviceIdentifier = androidInfo.id;
|
||
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
|
||
final iosInfo = await _deviceInfo.iosInfo;
|
||
// identifierForVendor(アプリ再インストールで変わる可能性あり)
|
||
deviceIdentifier = iosInfo.identifierForVendor ?? 'unknown-ios';
|
||
} else {
|
||
// その他のプラットフォーム
|
||
deviceIdentifier = 'unknown-platform';
|
||
}
|
||
|
||
// SHA256ハッシュ化(64文字の固定長文字列)
|
||
final bytes = utf8.encode(deviceIdentifier);
|
||
final digest = sha256.convert(bytes);
|
||
_cachedDeviceId = digest.toString();
|
||
|
||
debugPrint('Device ID (hashed): ${_cachedDeviceId!.substring(0, 8)}...');
|
||
|
||
return _cachedDeviceId!;
|
||
} catch (e) {
|
||
debugPrint('Error getting device ID: $e');
|
||
// エラー時はランダムなIDを生成(セッション中は同じIDを使用)
|
||
_cachedDeviceId = sha256.convert(utf8.encode('fallback-${DateTime.now().millisecondsSinceEpoch}')).toString();
|
||
return _cachedDeviceId!;
|
||
}
|
||
}
|
||
|
||
/// デバイス情報をリセット(テスト用)
|
||
static void reset() {
|
||
_cachedDeviceId = null;
|
||
}
|
||
}
|