Cara membuat login dan logout di flutter dengan PHP dan MySQL

Dalam pengembangan aplikasi, sistem login dan logout adalah fitur utama yang sering digunakan untuk otentikasi pengguna. Pada artikel ini, kita akan mempelajari cara membuat sistem login dan logout di aplikasi Flutter dengan menggunakan PHP untuk backend, MySQL untuk database, serta teknik hashing password untuk meningkatkan keamanan. Dengan menggunakan pendekatan ini, aplikasi Flutter Anda akan lebih aman dan terhindar dari risiko kebocoran data pengguna.

Langkah 1: Persiapan Backend (PHP + MySQL)

Sebelum membuat aplikasi Flutter, kita perlu menyiapkan backend yang akan menangani proses autentikasi. Di sisi backend, kita akan menggunakan PHP untuk berinteraksi dengan MySQL.

1.1. Membuat Database dan Tabel

Langkah pertama adalah membuat database dan tabel untuk menyimpan data pengguna. Kita akan membuat tabel user2 yang memiliki kolom id, name,username, dan password (yang akan disimpan dalam bentuk hash untuk keamanan). Berikut adalah query untuk membuat tabel tersebut di MySQL:

Membuat Database db_shop CREATE DATABASE `db_shop`

Membuat table user2


CREATE TABLE `user2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(700) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
 

1.2. Registrasi Pengguna dengan Hash Password

Ketika pengguna mendaftar, kita akan menyimpan password mereka dalam bentuk yang ter-enkripsi menggunakan bcrypt. PHP menyediakan fungsi password_hash() untuk melakukan ini.

Buat file php dengan nama register.php

<?php
// Koneksi ke database
$host = 'localhost';  // Ganti dengan host MySQL Anda
$dbname = 'db_shop';  // Ganti dengan nama database Anda
$username = 'root';  // Ganti dengan username MySQL Anda
$password = '';  // Ganti dengan password MySQL Anda

// Membuat koneksi
try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    // Set mode error PDO ke exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo 'Koneksi gagal: ' . $e->getMessage();
    exit;
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Ambil data dari form
    $nama = $_POST['nama'];
    $username = $_POST['username'];
    $password = $_POST['password'];  // Password yang dimasukkan oleh pengguna
    
    // Validasi form input (misalnya, memastikan username dan password tidak kosong)
    if (empty($username) || empty($password)) {
        echo "Username dan password harus diisi!";
        exit;
    }

    // Hash password menggunakan bcrypt (password_hash akan menghasilkan salt secara otomatis)
    $passwordHash = password_hash($password, PASSWORD_DEFAULT);

    // Query untuk menyimpan data pengguna baru dengan password yang sudah di-hash
    $stmt = $pdo->prepare("INSERT INTO user2 (name,username, password) VALUES (:nama, :username, :password)");
    $stmt->execute([
	'nama' => $nama,
        'username' => $username,
        'password' => $passwordHash,
    ]);

    echo "Pendaftaran berhasil!";
}
?>

<!-- Form untuk registrasi -->
<form method="POST" action="register.php">
<label for="username">Name:</label>
    <input type="text" id="username" name="nama" required>
    <br><br>
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required>
    <br><br>
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required>
    <br><br>
    <button type="submit">Daftar</button>
</form>

setelah disimpan jalankan form registrasi ini untuk menambah data pengguna di localhost, Di sini, kita menggunakan password_hash() untuk meng-hash password pengguna sebelum menyimpannya di database.

1.3. Proses Login dan Verifikasi Password

Untuk login, kita akan memverifikasi password pengguna dengan membandingkan password yang dimasukkan dengan hash yang tersimpan di database menggunakan password_verify().

buat file login3.php dilocalhost di folder project kita dan letakan kode berikut :

<?php
// Koneksi ke database
$servername = "localhost";
$username = "root"; // Ganti dengan username database Anda
$password = ""; // Ganti dengan password database Anda
$dbname = "db_shop"; // Ganti dengan nama database Anda

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Koneksi gagal: " . $conn->connect_error);
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Ambil data dari form
    $username = $_POST['username'];
    $password = $_POST['password'];

    // Cek apakah username ada di database
    $sql = "SELECT * FROM user2 WHERE username = '$username'";
    $result = $conn->query($sql);

    if ($result->num_rows > 0) {
        // Ambil data pengguna dari database
        $user = $result->fetch_assoc();

        // Verifikasi password dengan password_hash
        if (password_verify($password, $user['password'])) {
            //echo "Login berhasil!";
	    echo json_encode(["status" => "success", "message" => "Login berhasil"]);
        } else {
            //echo "Password salah!";
	    echo json_encode(["status" => "error", "message" => "Username atau password salah"]);
        }
    } else {
        echo "Username tidak ditemukan!";
    }
}

$conn->close();
?>

Di bagian ini, kita mencari username pengguna di database dan kemudian memverifikasi password dengan password_verify().

1.4. Membuat file logout

untuk sistem logout kita akan menggunakan session_destroy(); milik PHP, untuk itu buat file logout.php di folder project kita dilocalhost dan letakan kode berikut

<?php
// File: logout.php

// Memulai session (jika menggunakan session ID)
session_start();

// Menghancurkan session
session_destroy();

// Mengembalikan response JSON sukses
$response = array(“status” => “success”, “message” => “Logged out successfully”);

// Mengirimkan response dalam format JSON
header(‘Content-Type: application/json’);
echo json_encode($response);
?>

2.1. Menambahkan Dependency HTTP

Di dalam file pubspec.yaml, tambahkan dependency untuk paket http yang digunakan untuk melakukan request HTTP ke server.

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.4

2.2. Implementasi Halaman Login di Flutter

Kita akan membuat halaman login dan homepage di flutter, halaman login berisi dua input (username dan password) dan sebuah tombol untuk mengirimkan data ke server PHP,

pertama kita akan membuat project baru di flutter, setelah itu buat halaman homepage.dart, isikan kode dibawah ini

// Halaman Baru (HomePage)
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert'; // Pastikan ini ada!
import 'main.dart';

class AuthService {
  static const String baseUrl =
      "http://192.168.18.81/apiflutter"; // Ganti dengan URL API Anda

  // Fungsi untuk logout
  Future<void> logout() async {
    try {
      // URL endpoint logout
      final url = Uri.parse('$baseUrl/logout.php');

      // Mengirimkan request ke API logout
      final response = await http.post(url, headers: {
        'Content-Type': 'application/json',
        // Jika menggunakan token JWT, Anda bisa menambahkannya ke header
        'Authorization': 'Bearer YOUR_TOKEN', // Ganti dengan token jika ada
      });

      // Memeriksa status code dari response
      if (response.statusCode == 200) {
        final data = json.decode(response.body);

        if (data['status'] == 'success') {
          print('Logout berhasil: ${data['message']}');
          // Hapus data session atau token di aplikasi (misalnya menggunakan shared_preferences)
        } else {
          print('Logout gagal: ${data['message']}');
        }
      } else {
        print('Request gagal dengan status code: ${response.statusCode}');
      }
    } catch (e) {
      print('Error: $e');
    }
  }
}

class HomePage extends StatelessWidget {
  //const HomePage({super.key});
  final AuthService authService = AuthService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Halaman Utama")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment
              .center, // Mengatur agar item berada di tengah vertikal
          crossAxisAlignment: CrossAxisAlignment
              .center, // Mengatur agar item berada di tengah horizontal
          children: [
            Text("Selamat Datang", style: TextStyle(fontSize: 24)),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Center(
                  child: ElevatedButton(
                    onPressed: () async {
                      // Panggil fungsi logout ketika tombol ditekan
                      await authService.logout();
                      // Setelah logout, bisa mengarahkan pengguna kembali ke halaman login
                      // Navigator.pushReplacementNamed(LoginPage());
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => LoginPage()),
                      );
                    },
                    child: Text("Logout"),
                  ),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

kemudian kita akan membuat halaman loginnya, ubah kode main.dart dengan kode berikut

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'homepage.dart';

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

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool _isLoading = false;
  String _message = "";

  Future<void> _login() async {
    final String username = _usernameController.text;
    final String password = _passwordController.text;

    if (username.isEmpty || password.isEmpty) {
      setState(() {
        _message = "Username dan password tidak boleh kosong!";
      });
      return;
    }

    setState(() {
      _isLoading = true;
    });

    // URL server Anda, misalnya: 'http://yourdomain.com/login.php'
    final String url = 'http://192.168.18.81/apiflutter/login3.php';

    try {
      final response = await http.post(
        Uri.parse(url),
        body: {
          'username': username,
          'password': password,
        },
      );

      final Map<String, dynamic> responseData = json.decode(response.body);

      setState(() {
        _isLoading = false;
        _message = responseData['message'];
      });

      if (responseData['status'] == 'success') {
        // Login berhasil
        ScaffoldMessenger.of(context);
        //.showSnackBar(SnackBar(content: Text('Login berhasil')));
        // Login berhasil
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('Login berhasil')));

        // Mengarahkan ke halaman HomePage setelah login berhasil
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
              builder: (context) =>
                  HomePage()), // Halaman baru yang ingin dituju
        );

        // Arahkan ke halaman lain
      } else {
        // Login gagal
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('Login gagal')));
      }
    } catch (e) {
      setState(() {
        _isLoading = false;
        _message = "Terjadi kesalahan jaringan!";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Login")),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _usernameController,
              decoration: InputDecoration(labelText: 'Username'),
            ),
            TextField(
              controller: _passwordController,
              obscureText: true,
              decoration: InputDecoration(labelText: 'Password'),
            ),
            SizedBox(height: 20),
            _isLoading
                ? CircularProgressIndicator()
                : ElevatedButton(
                    onPressed: _login,
                    child: Text('Login'),
                  ),
            SizedBox(height: 20),
            Text(_message),
          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: LoginPage(),
  ));
}

Pada kode di atas, kita membuat dua input untuk username dan password, kemudian mengirim data ini ke server PHP menggunakan http.post().

Setelah berhasil login pengguna akan masuk kehalaman homepage yang berisi tulisan selamat datang dan tombol logout.

Langkah 3: Pengujian

Sekarang, Anda dapat menguji aplikasi Flutter dan backend PHP untuk memastikan bahwa fitur login dan logout bekerja dengan baik. Pastikan server PHP berjalan dengan benar, dan aplikasi Flutter dapat berkomunikasi dengan backend melalui API.

note :

  1. Aktifkan server localhost dan mysql
  2. untuk URL di main.dart, http://192.168.18.81/apiflutter/login3.php ubah apiflutter sesuai dengan nama folder dimana project flutter anda diletakan. misalnya http://192.168.18.81/nama_folder_anda/login3.php

Kesimpulan

Dengan mengikuti langkah-langkah di atas, Anda telah berhasil membuat aplikasi login dan logout di Flutter yang terhubung dengan backend PHP dan MySQL. Menggunakan teknik password hashing memastikan bahwa password pengguna disimpan dengan aman di database, sehingga meningkatkan keamanan aplikasi Anda. Sistem ini juga memungkinkan integrasi yang mudah dengan API berbasis PHP, membuatnya cocok untuk berbagai aplikasi yang memerlukan autentikasi pengguna.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *