플러터(Flutter)는 구글에서 개발한 UI 프레임워크로, 다양한 플랫폼에서 동작하는 모바일 애플리케이션을 개발할 수 있도록 지원합니다. 이번 글에서는 플러터를 사용하여 소켓 통신을 위한 SSL/TLS 연결을 구현하는 방법에 대해 알아보겠습니다.
1. 패키지 추가
먼저, 아래의 패키지를 pubspec.yaml
파일에 추가해야 합니다.
dependencies:
flutter_socket_io: ^0.6.0
flutter_socket_io_example_helper: ^0.0.1
위의 패키지는 플러터에서 소켓 통신을 지원하기 위해 필요한 패키지입니다.
2. SSL/TLS 설정 구현
SSL/TLS 연결을 위해 flutter_socket_io: ^0.6.0
패키지에서 제공하는 IOWebSocket
을 사용할 수 있습니다. 다음은 예시 코드입니다.
import 'package:flutter_socket_io/flutter_socket_io.dart';
import 'package:flutter_socket_io/socket_io_manager.dart';
final SocketIOManager socketIOManager = SocketIOManager();
void connectToServer() async {
SocketIO socket = await socketIOManager.createInstance(SocketOptions(
// 서버 URL 설정
'https://example.com',
enableLogging: true,
transports: [Transports.WEB_SOCKET], // 웹소켓 사용
secure: true, // SSL/TLS 연결
query: {
// 추가적인 쿼리 파라미터 설정 (선택)
'token': '<YOUR_TOKEN>',
}));
socket.onConnect((data) {
print('Connected to server: $data');
});
socket.onDisconnect((data) {
print('Disconnected from server: $data');
});
socket.emit('join_room', ['room1']); // 예시로 join_room 이벤트 전송
}
위 코드에서는 SocketOptions
를 사용하여 소켓 연결을 설정하고, socketIOManager.createInstance()
를 통해 소켓 인스턴스를 만들고 연결합니다. secure
옵션을 true
로 설정하여 SSL/TLS 연결을 가능하게 합니다. 연결이 성공하면 onConnect
콜백이 호출되고, 연결이 끊어지면 onDisconnect
콜백이 호출됩니다.
3. SSL 인증서 처리
SSL/TLS 연결을 위해 서버의 SSL 인증서를 신뢰할 수 있도록 해야 합니다. Android 및 iOS에서는 서버의 인증서를 포함한 Intermediate CA 인증서를 상수로 지정하여 인증서 체인을 생성해야 합니다.
Android의 경우, android/app/src/main/res/raw
폴더에 <your_certificate>.cer
파일을 추가한 후, MainActivity.java
파일을 열고 아래 코드를 추가합니다.
import androidx.annotation.NonNull;
import android.os.Bundle;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugin.common.MethodChannel;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends FlutterActivity {
private static final String METHOD_CHANNEL = "com.example/flutter_ssl_pinning";
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), METHOD_CHANNEL).setMethodCallHandler(
(call, result) -> {
if (call.method.equals("getCertificate")) {
// SSL 인증서 반환
result.success(getCertificate());
} else {
result.notImplemented();
}
});
}
private byte[] getCertificate() {
InputStream inputStream = getResources().openRawResource(R.raw.your_certificate);
try {
int size = inputStream.available();
byte[] buffer = new byte[size];
inputStream.read(buffer);
inputStream.close();
return buffer;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
iOS의 경우, Xcode를 열고 프로젝트를 선택한 후, Runner > Runner > Copy Bundle Resources
를 클릭하여 인증서를 추가한 후, AppDelegate.swift
파일을 열고 아래 코드를 추가합니다.
import Flutter
class AppDelegate: FlutterAppDelegate {
let METHOD_CHANNEL = "com.example/flutter_ssl_pinning"
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let certificate Channel = FlutterMethodChannel(name: METHOD_CHANNEL, binaryMessenger: controller.binaryMessenger)
certificateChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
if call.method == "getCertificate" {
// SSL 인증서 반환
result(self.getCertificate())
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func getCertificate() -> Data {
let path = Bundle.main.path(forResource: "your_certificate", ofType: "cer")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
return data
}
}
위 코드에서는 MethodChannel
을 사용하여 getCertificate()
를 호출하면 인증서 데이터를 반환합니다. 이후 flutter_socket_io
패키지에서 인증서를 사용할 수 있습니다.