token_storage 1.0.0 copy "token_storage: ^1.0.0" to clipboard
token_storage: ^1.0.0 copied to clipboard

A Flutter wrapper around flutter_secure_storage for managing an auth token pair and generic secure key-value storage, with fresh-install cleanup.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:token_storage/token_storage.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await TokenStorage.init();
  runApp(const TokenStorageExampleApp());
}

class TokenStorageExampleApp extends StatelessWidget {
  const TokenStorageExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'token_storage example', home: const HomePage());
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _status = 'No token';
  final _nameController = TextEditingController();
  String? _storedName;
  _Note? _storedNote;

  @override
  void initState() {
    super.initState();
    TokenStorage.i.setTokenListener(_onTokenChanged);
    _refreshStatus();
  }

  @override
  void dispose() {
    TokenStorage.i.removeTokenListener();
    _nameController.dispose();
    super.dispose();
  }

  void _onTokenChanged(TokenPair? token) {
    setState(() {
      _status = token == null
          ? 'Logged out (listener fired)'
          : 'Logged in (listener fired)';
    });
  }

  Future<void> _refreshStatus() async {
    final hasToken = await TokenStorage.i.hasToken;
    if (!mounted) return;
    setState(() => _status = hasToken ? 'Has token' : 'No token');
  }

  Future<void> _login() async {
    final now = DateTime.now();
    await TokenStorage.i.saveToken(
      TokenPair(
        accessToken: 'demo-access-${now.millisecondsSinceEpoch}',
        refreshToken: 'demo-refresh-${now.millisecondsSinceEpoch}',
        createdAt: now,
        updatedAt: now,
      ),
    );
  }

  Future<void> _silentlyRefresh() async {
    final current = await TokenStorage.i.token;
    if (current == null) return;
    await TokenStorage.i.updateToken(
      TokenPair(
        accessToken: 'demo-access-refreshed',
        refreshToken: current.refreshToken,
        createdAt: current.createdAt,
        updatedAt: DateTime.now(),
      ),
    );
    if (!mounted) return;
    await _refreshStatus();
  }

  Future<void> _logout() => TokenStorage.i.clearToken();

  Future<void> _saveName() async {
    await TokenStorage.i.put('display_name', _nameController.text);
    if (!mounted) return;
    final stored = await TokenStorage.i.get('display_name');
    if (!mounted) return;
    setState(() => _storedName = stored);
  }

  Future<void> _saveNote() async {
    await TokenStorage.i.putObject(
      'last_note',
      _Note(text: _nameController.text, createdAt: DateTime.now()),
      (note) => note.toJson(),
    );
    if (!mounted) return;
    final note = await TokenStorage.i.getObject('last_note', _Note.fromJson);
    if (!mounted) return;
    setState(() => _storedNote = note);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('token_storage example')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text('Status: $_status'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _login,
              child: const Text('Login (saveToken)'),
            ),
            ElevatedButton(
              onPressed: _silentlyRefresh,
              child: const Text('Silent refresh (updateToken)'),
            ),
            ElevatedButton(
              onPressed: _logout,
              child: const Text('Logout (clearToken)'),
            ),
            const Divider(height: 32),
            TextField(
              controller: _nameController,
              decoration: const InputDecoration(labelText: 'Display name'),
            ),
            ElevatedButton(
              onPressed: _saveName,
              child: const Text('Save name (put/get)'),
            ),
            if (_storedName != null) Text('Stored name: $_storedName'),
            const Divider(height: 32),
            ElevatedButton(
              onPressed: _saveNote,
              child: const Text('Save note (putObject/getObject)'),
            ),
            if (_storedNote != null)
              Text(
                'Stored note: ${_storedNote!.text} (${_storedNote!.createdAt})',
              ),
          ],
        ),
      ),
    );
  }
}

/// A tiny typed object used to demonstrate [TokenStorage.putObject] and
/// [TokenStorage.getObject], which store/retrieve JSON-serializable objects
/// instead of raw strings.
class _Note {
  const _Note({required this.text, required this.createdAt});

  final String text;
  final DateTime createdAt;

  Map<String, dynamic> toJson() => {
    'text': text,
    'createdAt': createdAt.toIso8601String(),
  };

  factory _Note.fromJson(Map<String, dynamic> json) => _Note(
    text: json['text'] as String,
    createdAt: DateTime.parse(json['createdAt'] as String),
  );
}
0
likes
0
points
--
downloads

Publisher

verified publisherkishormainali.com

Weekly Downloads

A Flutter wrapper around flutter_secure_storage for managing an auth token pair and generic secure key-value storage, with fresh-install cleanup.

Repository (GitHub)
View/report issues

Topics

#secure-storage #authentication #token #flutter-secure-storage

License

unknown (license)

Dependencies

flutter, flutter_secure_storage, shared_preferences

More

Packages that depend on token_storage