주뇽's 저장소

[Flutter] Flutter 에서 GetX를 이용한 인터셉터 및 토큰 갱신 방법 본문

웹개발/Flutter

[Flutter] Flutter 에서 GetX를 이용한 인터셉터 및 토큰 갱신 방법

뎁쭌 2024. 5. 31. 19:07
728x90
반응형

 

https://pub.dev/packages/get

 

get | Flutter package

Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.

pub.dev

 

Flutter에서 GetX를 이용한 인터셉터 및 토큰 갱신 방법

개요

이 글에서는 Flutter에서 GetX 패키지를 사용하여 인터셉터를 설정하고, JWT 토큰을 갱신하는 방법을 믹스인을 사용하여 공통화하는 방법을 설명한다. 이를 통해 코드 재사용성을 높이고 유지보수를 쉽게 할 수 있다.

JWT 토큰 개요

  • 액세스 토큰: 사용자가 인증된 후 API에 접근할 수 있는 권한을 나타내는 토큰이다. 짧은 유효기간을 가지며, 만료되면 재발급 받아야 한다.
  • 리프레시 토큰: 액세스 토큰이 만료될 때 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰이다. 상대적으로 긴 유효기간을 가지며, 서버에서 관리된다.

GetX 인터셉터 설정

인터셉터를 통해 모든 HTTP 요청에 JWT 토큰을 추가하고, 401 응답 시 토큰을 자동으로 갱신한다.

GetConnect의 기본 설정

GetConnect는 GetX 패키지의 HTTP 클라이언트로, 이를 통해 HTTP 요청을 쉽게 보낼 수 있다. 기본 설정은 다음과 같이 한다:

class ApiClient extends GetConnect {
  @override
  void onInit() {
    httpClient.baseUrl = 'https://your-api-url.com';
  }
}

httpClient.baseUrl을 통해 모든 요청의 기본 URL을 설정할 수 있다.

인터셉터 설정

HTTP 요청 시 토큰을 추가하고, 응답에서 401 오류가 발생할 경우 토큰을 갱신하도록 인터셉터를 설정한다.

TokenManager 믹스인 생성

공통 기능을 믹스인으로 구현하여 여러 클래스에서 재사용할 수 있게 한다.

import 'package:get/get.dart';
import 'package:get/get_connect/http/src/request/request.dart';

mixin TokenManager on GetConnect {
  @override
  void onInit() {
    super.onInit();
    httpClient.baseUrl = 'https://your-api-url.com';

    httpClient.addRequestModifier<void>((Request request) async {
      final token = await getAccessToken();
      if (token != null) {
        request.headers['Authorization'] = 'Bearer $token';
      }
      return request;
    });

    httpClient.addResponseModifier((request, response) async {
      if (response.statusCode == 401) {
        final newAccessToken = await _refreshToken();
        if (newAccessToken != null) {
          request.headers['Authorization'] = 'Bearer $newAccessToken';
          return httpClient.request(
            request.method,
            request.url.toString(),
            body: request.bodyBytes,
            headers: request.headers,
          );
        }
      }
      return response;
    });
  }

  Future<String?> _refreshToken() async {
    final refreshToken = await getRefreshToken();
    if (refreshToken == null) return null;

    final response = await post(
      '/reissue',
      {},
      headers: {
        'Cookie': 'refresh=$refreshToken',
      },
    );

    if (response.statusCode == 200) {
      String? newRefreshToken = response.headers?['set-cookie'];
      String? accessToken = response.headers?['Authorization'];

      if (accessToken != null && newRefreshToken != null) {
        await storeTokens(accessToken, newRefreshToken);
        return accessToken;
      }
    }
    return null;
  }

  Future<String?> getAccessToken() async {
    // access token을 가져오는 로직 구현
  }

  Future<String?> getRefreshToken() async {
    // refresh token을 가져오는 로직 구현
  }

  Future<void> storeTokens(String accessToken, String refreshToken) async {
    // access token과 refresh token을 저장하는 로직 구현
  }
}

다른 클래스에서 TokenManager 사용

다른 클래스에서 TokenManager 믹스인을 사용하여 공통 기능을 재사용한다.

ApiService 클래스

import 'package:get/get.dart';
import 'token_manager.dart';

class ApiService extends GetConnect with TokenManager {
  Future<Response> getData() => get('/data');
  Future<Response> postData(Map<String, dynamic> data) => post('/data', data);
}

결론

이 글에서는 Flutter에서 GetX를 사용하여 HTTP 요청에 인터셉터를 설정하고 JWT 토큰을 자동으로 갱신하는 방법을 다뤘다. TokenManager 클래스를 믹스인으로 구현하여 여러 클래스에서 공통 기능을 쉽게 재사용할 수 있도록 하였다. 이를 통해 코드의 재사용성을 높이고 유지보수를 용이하게 할 수 있다.