Flutter 로그인 상태 유지하기: shared_preferences 사용법

사용자가 앱을 사용하는 과정에서 로그인은 필수적인 단계이며, 한 번 로그인한 후에는 앱을 재시작해도 다시 로그인하지 않아도 되는 사용자 경험을 제공하는 것이 중요합니다. 이번 글에서는 Flutter 앱에서 shared_preferences 패키지를 사용하여 flutter 로그인 상태를 유지하는 방법을 소개합니다. 이 기능을 구현함으로써 사용자가 앱을 재시작할 때마다 로그인 화면을 건너뛰고 바로 메인 화면으로 이동할 수 있게 됩니다.

패키지 설치

Flutter 개발 환경 설정과 shared_preferences 패키지의 설치가 필수적입니다. pubspec.yaml 파일에 다음과 같이 shared_preferences 패키지를 추가하여 시작합니다

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.6

로그인 상태 확인하기

앱의 시작점인 main.dart 파일에서 로그인 상태를 확인하고, 그 상태에 따라 적절한 화면으로 이동하는 로직을 구현합니다. FutureBuilder를 사용하여 비동기적으로 로그인 상태를 불러온 후, 상태에 따라 로그인 화면 또는 홈 화면으로 이동시킵니다.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'login_screen.dart';
import 'home_screen.dart';

// 앱의 메인 함수, 앱 실행의 시작점입니다.
void main() => runApp(MyApp());

// StatelessWidget을 상속받는 MyApp 클래스를 정의합니다.
// 이 클래스는 앱의 루트 위젯 역할을 합니다.
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // MaterialApp 위젯을 반환하여 앱의 기본적인 디자인을 설정합니다.
    return MaterialApp(
      // 앱의 홈 화면으로 FutureBuilder를 사용합니다.
      // FutureBuilder는 비동기 작업의 결과에 따라 위젯을 구성할 수 있게 해줍니다.
      home: FutureBuilder(
        // _getLoginStatus() 함수의 결과를 기다립니다.
        // 이 함수는 사용자의 로그인 상태를 비동기적으로 가져옵니다.
        future: _getLoginStatus(),
        // future가 완료되면 이 builder 함수가 실행됩니다.
        builder: (context, snapshot) {
          // 비동기 작업이 완료된 경우
          if (snapshot.connectionState == ConnectionState.done) {
            // snapshot.data가 true라면, 사용자가 로그인 상태이므로 HomeScreen을 보여줍니다.
            // 그렇지 않다면 LoginScreen을 보여줍니다.
            return snapshot.data == true ? HomeScreen() : LoginScreen();
          } else {
            // 비동기 작업이 아직 완료되지 않았다면 로딩 인디케이터를 보여줍니다.
            return CircularProgressIndicator();
          }
        },
      ),
    );
  }

  // 비동기 함수 _getLoginStatus를 정의합니다.
  // 이 함수는 shared_preferences를 사용하여 저장된 로그인 상태를 불러옵니다.
  Future<bool> _getLoginStatus() async {
    // SharedPreferences의 인스턴스를 비동기적으로 가져옵니다.
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    // 'isLoggedIn' 키를 사용하여 저장된 로그인 상태를 불러옵니다.
    // 해당 키가 없다면 기본값으로 false를 반환합니다.
    return prefs.getBool('isLoggedIn') ?? false;
  }
}

로그인 처리하기

login_screen.dart에서 사용자가 로그인 버튼을 클릭하면 shared_preferences를 사용하여 로그인 상태를 true로 설정합니다. 이렇게 하면 사용자가 앱을 재시작해도 로그인 상태가 유지됩니다.

// StatelessWidget을 상속받는 LoginScreen 클래스를 정의합니다.
// 이 클래스는 로그인 화면을 구성하는 위젯입니다.
class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Scaffold 위젯을 반환하여 기본적인 앱의 레이아웃 구조를 제공합니다.
    return Scaffold(
      // AppBar를 사용하여 앱의 상단에 타이틀 바를 생성합니다.
      appBar: AppBar(
        title: Text('Login Screen'), // 타이틀 바에 표시될 텍스트입니다.
      ),
      // Scaffold의 body에는 로그인 버튼을 중앙에 배치합니다.
      body: Center(
        // ElevatedButton을 사용하여 로그인 버튼을 생성합니다.
        child: ElevatedButton(
          child: Text('Login'), // 버튼에 표시될 텍스트입니다.
          onPressed: () async { // 버튼이 클릭되었을 때 실행될 콜백 함수입니다.
            // SharedPreferences의 인스턴스를 비동기적으로 가져옵니다.
            final SharedPreferences prefs = await SharedPreferences.getInstance();
            // 'isLoggedIn' 키에 대해 true 값을 저장하여 사용자가 로그인했음을 표시합니다.
            await prefs.setBool('isLoggedIn', true);
            // 로그인 후, Navigator를 사용하여 HomeScreen으로 화면을 전환합니다.
            // pushReplacement를 사용하여 현재 화면을 HomeScreen으로 교체합니다.
            Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => HomeScreen()));
          },
        ),
      ),
    );
  }
}

로그인 버튼을 누른후 앱을 종료하고 다시 실행하면 로그인이 된 상태기 때문에 로그아웃 화면이 보여집니다.

flutter-로그인

로그아웃 처리하기

마찬가지로 home_screen.dart에서 로그아웃 버튼을 구현하고, 버튼 클릭 시 로그인 상태를 false로 설정합니다. 이는 사용자가 로그아웃하면 다음 앱 시작 시 로그인 화면으로 이동해야 함을 의미합니다.

// StatelessWidget을 상속받는 HomeScreen 클래스를 정의합니다.
// 이 클래스는 앱의 홈 화면을 구성하는 위젯입니다.
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Scaffold 위젯을 사용하여 기본적인 앱 레이아웃을 제공합니다.
    return Scaffold(
      // AppBar를 사용하여 화면 상단에 앱 바를 생성합니다.
      appBar: AppBar(
        title: Text('Home Screen'), // 앱 바에 표시될 타이틀입니다.
      ),
      // Scaffold의 body에서 로그아웃 버튼을 중앙에 배치합니다.
      body: Center(
        // ElevatedButton을 사용하여 로그아웃 버튼을 생성합니다.
        child: ElevatedButton(
          child: Text('Logout'), // 버튼에 표시될 텍스트입니다.
          onPressed: () async { // 버튼이 클릭되었을 때 실행될 콜백 함수입니다.
            // SharedPreferences의 인스턴스를 비동기적으로 가져옵니다.
            final SharedPreferences prefs = await SharedPreferences.getInstance();
            // 'isLoggedIn' 키에 대해 false 값을 저장하여 사용자가 로그아웃했음을 표시합니다.
            await prefs.setBool('isLoggedIn', false);
            // 로그아웃 후, Navigator를 사용하여 LoginScreen으로 화면을 전환합니다.
            // pushReplacement를 사용하여 현재 화면을 LoginScreen으로 교체합니다.
            Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => LoginScreen()));
          },
        ),
      ),
    );
  }
}
flutter-로그아웃

로그아웃 후 앱을 종료하면 로그아웃이 된 상태기 때문에 로그인 화면 보여집니다.

마무리

간단한 예제를 통해 Flutter 앱에서 로그인 상태를 유지하는 방법을 알아보았습니다. shared_preferences 패키지를 사용하면 사용자의 로그인 상태를 간편하게 관리할 수 있으며, 이는 사용자 경험을 크게 향상시키는 방법 중 하나입니다. 읽어주셔서 감사합니다.

Leave a Comment