Integrasi API: Login & Penyimpanan Token
Tujuan Pembelajaran
Setelah mengikuti materi ini, siswa mampu: 1. Membuat model untuk respon Login (Token & User Data) menggunakan app.quicktype.io. 2. Menyimpan Token sesi menggunakan flutter_secure_storage. 3. Melakukan navigasi halaman menggunakan go_router. 4. Memahami alur autentikasi (Login -> Simpan Token -> Home).
Pertanyaan Pemantik
Setelah kita berhasil Register, bagaimana caranya aplikasi tahu kalau kita "sudah login" setiap kali kita membukanya?
Jawabannya adalah Token. Bayangkan token ini seperti "Tiket Masuk" atau stempel di tangan saat masuk wahana. Kita harus menyimpannya baik-baik agar tidak perlu login ulang terus-menerus.
1. Persiapan: Endpoint & Model
Kita akan membedah endpoint Login terlebih dahulu.
- URL:
{{ API_URL }}/login(Ambil dari.env) - Method:
POST - Body:
{ "email": "contoh@gm.com", "password": "1234567890" } - Response Sukses (200 OK):
{ "token": "eyJhbGciOiJIUzI1NiIsIn...", "user": { "email": "contoh@gm.com", "id": 1, "name": "admin", "role": "admin" } }
Membuat Model AuthResponse
Response login kali ini mengandung objek yang kompleks. Kita akan buat modelnya otomatis.
- Copy JSON Response di atas.
- Buka app.quicktype.io.
- Set Name:
AuthResponse. - Set Language:
Dart. - Copy hasilnya.
- Buat file
lib/models/auth_response_model.dartdan paste kodenya.
2. Instalasi Flutter Secure Storage
Kita tidak boleh menyimpan Token penting di sembarang tempat (seperti SharedPreferences biasa). Kita butuh tempat yang terenkripsi.
- Jalankan perintah di terminal:
flutter pub add flutter_secure_storage - (Khusus Android) Kita perlu mensetting
minSdkVersionmenjadi 18 atau lebih diandroid/app/build.gradle.
3. Update Auth Service
Kita akan update auth_service.dart untuk menambahkan fitur Login dan simpan token.
Buka lib/services/auth_service.dart dan tambahkan method login:
// Tambahkan import ini
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import '../models/auth_response_model.dart';
class AuthService {
// ... kode lama (register) ...
// Inisialisasi storage
final storage = const FlutterSecureStorage();
// Fungsi Login
Future<bool> login({
required String email,
required String password
}) async {
var url = Uri.parse('$baseUrl/login');
var response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
"email": email,
"password": password
}),
);
if (response.statusCode == 200) {
// 1. Ubah JSON jadi Object Model
var data = authResponseFromJson(response.body);
// 2. Simpan Token ke Secure Storage
await storage.write(key: 'auth_token', value: data.token);
// 3. (Opsional) Simpan data user jika perlu
await storage.write(key: 'user_name', value: data.user.name);
return true;
} else {
throw Exception('Login Gagal: Email atau Password salah!');
}
}
}
4. Integrasi ke Halaman Login
Sekarang kita hubungkan UI Login dengan Service baru ini.
Skenario:
Jika Login berhasil -> Pindah ke Halaman Home (menggunakan go_router).
Buka lib/pages/login_page.dart:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; // Import GoRouter
import '../services/auth_service.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
final AuthService authService = AuthService();
bool isLoading = false;
void login() async {
setState(() { isLoading = true; });
try {
bool success = await authService.login(
email: emailController.text,
password: passwordController.text,
);
if (success) {
if (!mounted) return; // Cek widget masih aktif
// Navigasi ke Home menggunakan GoRouter
context.go('/home'); // Sesuaikan dengan route path kalian
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Login Berhasil!")),
);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(e.toString())),
);
} finally {
if (mounted) {
setState(() { isLoading = false; });
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Masuk Aplikasi")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(controller: emailController, decoration: const InputDecoration(labelText: "Email")),
TextField(controller: passwordController, decoration: const InputDecoration(labelText: "Password"), obscureText: true),
const SizedBox(height: 20),
isLoading
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: login,
child: const Text("Masuk"),
),
],
),
),
);
}
}
Tugas Mandiri: Logout
Kalian sudah berhasil menyimpan token (Login). Sekarang tugas kalian adalah membuat fitur Logout.
Petunjuk:
1. Logout itu sederhana: Kita hanya perlu menghapus token yang tersimpan di flutter_secure_storage.
2. Jika token dihapus, aplikasi akan menganggap user belum login.
3. Cari tahu cara menghapus data di dokumentasi package flutter_secure_storage di pub.dev.
Tantangan:
Buat tombol Logout di Halaman Home. Ketika ditekan:
1. Hapus token dari storage.
2. Lempar user kembali ke halaman Login (context.go('/login')).
Selamat mencoba!