티스토리 뷰

Flutter에서 인증된 요청을 처리하는 것은 보안이 중요한 애플리케이션 개발에서 필수적인 요소입니다. 특히 API와의 통신에서 민감한 데이터를 다루는 경우, 올바른 인증 구현이 핵심입니다. 이번 블로그에서는 Flutter에서 HTTP 패키지를 활용해 인증된 요청을 구현하는 방법을 소개합니다.

참고. Make authenticated requests

Flutter에서 인증된 요청이 중요한 이유

Flutter 애플리케이션 개발 시, 인증된 요청은 다음과 같은 이유로 중요합니다:

  1. 보안 유지: 민감한 데이터를 보호하고, 인증된 사용자만이 리소스에 접근할 수 있도록 합니다.
  2. API 제한 준수: 많은 API는 인증 토큰을 요구하며, 이는 사용량을 추적하거나 데이터 접근을 제한하는 데 사용됩니다.
  3. 사용자 관리: 사용자별로 맞춤화된 경험을 제공하기 위해 필요합니다.

Flutter에서 인증된 요청의 구현 과정

1. HTTP 패키지 설치

Flutter에서는 http 패키지를 사용하여 네트워크 요청을 처리할 수 있습니다. pubspec.yaml에 다음을 추가합니다:

dependencies:
  http: ^0.15.0

그 후, flutter pub get 명령어를 실행하여 패키지를 설치합니다.

2. 기본적인 HTTP 요청 처리

Flutter에서 HTTP 요청은 http 패키지를 사용해 간단히 보낼 수 있습니다. 하지만 인증된 요청에서는 헤더에 인증 정보를 추가해야 합니다.

import 'package:http/http.dart' as http;

Future<void> makeAuthenticatedRequest() async {
  final url = Uri.parse('https://example.com/api/data');
  final token = 'your_auth_token_here'; // 인증 토큰

  final response = await http.get(
    url,
    headers: {
      'Authorization': 'Bearer $token',
      'Content-Type': 'application/json',
    },
  );

  if (response.statusCode == 200) {
    print('Response: ${response.body}');
  } else {
    print('Failed to fetch data: ${response.statusCode}');
  }
}

인증 토큰 관리

1. 저장 및 갱신

Flutter에서 인증 토큰을 안전하게 관리하려면 다음과 같은 접근 방법을 사용할 수 있습니다:

  • shared_preferences: 간단한 로컬 저장소로 적합.
  • Secure Storage: 민감한 데이터의 보안을 강화하기 위해 flutter_secure_storage를 사용.
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

final storage = FlutterSecureStorage();

// 토큰 저장
await storage.write(key: 'auth_token', value: token);

// 토큰 읽기
final token = await storage.read(key: 'auth_token');

2. 토큰 갱신

만료된 토큰을 처리하려면 API에서 제공하는 refresh_token을 사용해 새 토큰을 받아옵니다.

인증 요청의 실용 사례

1. 사용자 로그인

사용자가 로그인할 때 API로부터 인증 토큰을 받아 로컬에 저장합니다.

Future<void> loginUser(String username, String password) async {
  final response = await http.post(
    Uri.parse('https://example.com/api/login'),
    body: {
      'username': username,
      'password': password,
    },
  );

  if (response.statusCode == 200) {
    final token = response.body['token'];
    await storage.write(key: 'auth_token', value: token);
    print('Login successful');
  } else {
    print('Login failed');
  }
}

2. 보호된 리소스 접근

로그인 후, 저장된 토큰을 사용해 보호된 API에 접근합니다.

Flutter에서 인증된 요청을 구현할 때의 팁

  1. 에러 처리: 요청 실패 시 사용자에게 적절히 알림을 제공하고, 디버깅 정보를 남기세요.
  2. 네트워크 보안: HTTPS를 사용하여 데이터 암호화를 보장하세요.
  3. 비동기 처리: asyncawait 키워드를 활용하여 비동기 작업을 처리하세요.
  4. 로깅: 디버깅을 위해 네트워크 요청 및 응답을 로깅하는 습관을 가지세요.

결론

Flutter에서 인증된 요청을 올바르게 구현하면 애플리케이션의 보안을 강화하고 사용자 신뢰를 높일 수 있습니다. 이번 포스트에서 다룬 HTTP 요청 및 인증 토큰 관리 방법을 활용해 보안이 강력한 앱을 개발해 보세요.

 

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;

Future<Album> fetchAlbum() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/albums/1'),
    // Send authorization headers to the backend.
    headers: {
      HttpHeaders.authorizationHeader: 'Basic your_api_token_here',
    },
  );
  final responseJson = jsonDecode(response.body) as Map<String, dynamic>;

  return Album.fromJson(responseJson);
}

class Album {
  final int userId;
  final int id;
  final String title;

  const Album({
    required this.userId,
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return switch (json) {
      {
        'userId': int userId,
        'id': int id,
        'title': String title,
      } =>
        Album(
          userId: userId,
          id: id,
          title: title,
        ),
      _ => throw const FormatException('Failed to load album.'),
    };
  }
}