Tutorial Android #6: Login Multi-Level (Admin, Petugas, Nasabah) dan Manajemen Session

Tutorial Android #6: Login Multi-Level (Admin, Petugas, Nasabah) dan Manajemen Session

Halo para penjaga pintu aplikasi! Setelah berhasil membuat login di tutorial #3, sekarang kita akan menyempurnakan sistem login multi-level agar aplikasi bisa membedakan role admin, petugas, dan nasabah. Setelah login, user akan diarahkan ke dashboard yang sesuai. Kita juga akan memperkuat manajemen session dan menambahkan fitur logout dengan konfirmasi dialog. Siap jadi resepsionis canggih?

😂 Joke role: "Kenapa admin, petugas, dan nasabah beda dashboard? Karena kalau disatukan, bisa kacau kayak warung yang pembeli dan penjualnya barengan!" 🏪

Apa yang akan kita lakukan?

  • ✅ Memastikan response login dari API mengirimkan data role.
  • ✅ Menyimpan role di SessionManager (sudah dilakukan di tutorial #3).
  • ✅ Membuat activity terpisah untuk setiap role: NasabahDashboardActivity, PetugasDashboardActivity, AdminDashboardActivity.
  • ✅ Memodifikasi LoginActivity untuk mengarahkan ke dashboard sesuai role.
  • ✅ Menambahkan pengecekan session di setiap activity (jika tidak login, redirect ke LoginActivity).
  • ✅ Membuat menu logout di setiap dashboard dengan konfirmasi dialog (AlertDialog).
  • ✅ Membersihkan session dan mengarahkan kembali ke LoginActivity setelah logout.
  • ✅ Menangani kasus token expired (misal response 401) dengan logout otomatis.

📁 Langkah 1: Memastikan Response Login Mengandung Role

Di tutorial #3, kita sudah membuat LoginResponse yang memiliki inner class User dengan field role. Pastikan di backend Laravel, endpoint /api/login mengembalikan objek user yang mencakup role (seperti yang sudah dibuat di tutorial #3 Laravel).

Contoh response yang diharapkan:

{
    "message": "Login sukses!",
    "user": {
        "id": 1,
        "name": "Admin Bank",
        "email": "admin@bank.com",
        "role": "admin"
    },
    "token": "1|sdfsdf..."
}

Langkah 2: Membuat Activity untuk Setiap Role

Kita akan buat tiga activity baru:

  • NasabahDashboardActivity (sudah kita buat sebagai DashboardActivity di tutorial #4, bisa kita rename atau biarkan).
  • PetugasDashboardActivity (akan kita buat di tutorial selanjutnya, untuk sekarang bisa dibuat dummy).
  • AdminDashboardActivity (dummy untuk sekarang).

Untuk sementara, kita buat activity sederhana dengan TextView yang menunjukkan role. Misal PetugasDashboardActivity.java:

package com.example.banktabunganapp;

import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class PetugasDashboardActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_petugas_dashboard);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("Dashboard Petugas");

        TextView tvInfo = findViewById(R.id.tvInfo);
        tvInfo.setText("Selamat datang, Petugas! Fitur akan segera hadir.");
    }
}

Layout activity_petugas_dashboard.xml sederhana:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#28a745"
        app:titleTextColor="#fff"
        app:navigationIcon="?attr/homeAsUpIndicator"/>

    <TextView
        android:id="@+id/tvInfo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="18sp"/>
</LinearLayout>

Lakukan hal serupa untuk AdminDashboardActivity dengan warna berbeda (misal background toolbar merah).

Langkah 3: Memodifikasi LoginActivity untuk Redirect Berdasarkan Role

Di tutorial #3, kita sudah memiliki method navigateToDashboard(). Pastikan kodenya seperti ini:

private void navigateToDashboard() {
    String role = sessionManager.getUserRole(); // ambil dari SessionManager
    Intent intent;
    if ("admin".equalsIgnoreCase(role)) {
        intent = new Intent(LoginActivity.this, AdminDashboardActivity.class);
    } else if ("petugas".equalsIgnoreCase(role)) {
        intent = new Intent(LoginActivity.this, PetugasDashboardActivity.class);
    } else {
        intent = new Intent(LoginActivity.this, NasabahDashboardActivity.class); // atau DashboardActivity
    }
    startActivity(intent);
    finish();
}

Pastikan di SessionManager ada method getUserRole() yang mengembalikan string role. Kita sudah membuatnya di tutorial #3.

Langkah 4: Menambahkan Pengecekan Session di Setiap Dashboard

Setiap kali activity dashboard dibuka, kita harus memeriksa apakah user masih login. Jika tidak (token null), langsung redirect ke LoginActivity. Ini penting karena bisa saja session dihapus oleh aplikasi di tempat lain. Buat method checkSession() di setiap dashboard:

private void checkSession() {
    if (!sessionManager.isLoggedIn()) {
        // Token tidak ada, langsung ke login
        startActivity(new Intent(this, LoginActivity.class));
        finish();
    }
}

Panggil method ini di onCreate() sebelum melakukan apapun:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nasabah_dashboard);
    sessionManager = new SessionManager(this);
    checkSession();
    // ... sisanya
}

Langkah 5: Menambahkan Fitur Logout dengan Konfirmasi Dialog

Di setiap dashboard, tambahkan menu logout di toolbar (atau tombol). Kita akan buat menu item di res/menu/menu_dashboard.xml (jika belum ada).

menu_dashboard.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_profile"
        android:title="Profil"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_logout"
        android:title="Logout"
        app:showAsAction="never"/>
</menu>

Kemudian di setiap DashboardActivity, override onCreateOptionsMenu dan onOptionsItemSelected:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_dashboard, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_profile) {
        startActivity(new Intent(this, ProfileActivity.class));
        return true;
    } else if (item.getItemId() == R.id.action_logout) {
        showLogoutConfirmation();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Method showLogoutConfirmation() menggunakan AlertDialog:

private void showLogoutConfirmation() {
    new AlertDialog.Builder(this)
        .setTitle("Konfirmasi Logout")
        .setMessage("Apakah Anda yakin ingin keluar?")
        .setPositiveButton("Ya", (dialog, which) -> {
            // Hapus session
            sessionManager.logout();
            // Arahkan ke login
            startActivity(new Intent(this, LoginActivity.class));
            finish();
        })
        .setNegativeButton("Batal", null)
        .show();
}
😆 "Logout itu kayak keluar rumah: pastikan pintu udah dikunci (session dihapus) biar nggak kemasukan maling!" 🔒

⚠Langkah 6: Menangani Token Expired (401)

Jika token yang kita kirim ke API sudah tidak valid (misal kadaluarsa atau dihapus di server), server akan mengembalikan response 401 Unauthorized. Kita bisa menangani ini secara global dengan menambahkan interceptor di Retrofit, atau di setiap panggilan API.

Kita bisa membuat class ApiClient menambahkan interceptor untuk cek response 401. Tapi untuk sederhana, kita bisa menangani di setiap callback onResponse dengan mengecek kode 401:

if (response.code() == 401) {
    // Token expired, logout otomatis
    sessionManager.logout();
    startActivity(new Intent(CurrentActivity.this, LoginActivity.class));
    finish();
    return;
}

Contoh di DashboardActivity saat memuat saldo:

@Override
public void onResponse(Call<SaldoResponse> call, Response<SaldoResponse> response) {
    if (response.code() == 401) {
        sessionManager.logout();
        startActivity(new Intent(DashboardActivity.this, LoginActivity.class));
        finish();
        return;
    }
    // ... handle sukses
}

Ini akan membuat pengguna logout otomatis jika token tidak valid, dan mereka harus login ulang.

Langkah 7: Menambahkan Fungsi Update User di SessionManager (Opsional)

Jika di profil pengguna mengubah nama/email, kita perlu memperbarui data di SessionManager. Tambahkan method di SessionManager.java:

public void updateUser(String name, String email) {
    editor.putString(KEY_USER_NAME, name);
    editor.putString(KEY_USER_EMAIL, email);
    editor.commit();
}

Panggil method ini setelah berhasil update profil di ProfileActivity.

Langkah 8: Uji Coba

  1. Login sebagai nasabah, pastikan masuk ke NasabahDashboardActivity.
  2. Login sebagai petugas, pastikan masuk ke PetugasDashboardActivity.
  3. Login sebagai admin, pastikan masuk ke AdminDashboardActivity.
  4. Di setiap dashboard, coba klik menu Logout. Muncul dialog konfirmasi. Setuju, maka kembali ke LoginActivity.
  5. Coba akses langsung dashboard via intent (misal dengan menekan tombol back setelah logout), harusnya langsung redirect ke login karena session sudah hilang.
  6. Simulasi token expired dengan mengubah manual token di SharedPreferences atau menghapus token di server. Saat aplikasi mencoba memuat data, seharusnya logout otomatis.
💡 Catatan: Untuk pengujian token expired, kamu bisa hapus token dari database Laravel (tabel personal_access_tokens) atau tunggu sampai kadaluarsa (jika ada pengaturan expiry).

Kesimpulan

  • ✅ Login multi-level berfungsi dengan baik, mengarahkan ke dashboard sesuai role.
  • ✅ SessionManager menyimpan token dan data user.
  • ✅ Setiap dashboard memiliki pengecekan session dan menu logout dengan konfirmasi.
  • ✅ Token expired ditangani dengan logout otomatis.

Di tutorial selanjutnya (#7: Dashboard Petugas – Transaksi Setor dan Tarik Tunai) kita akan membuat fitur transaksi untuk petugas. Sampai jumpa!


Daftar Tutorial Android (Lanjutan)

Lebih baru Lebih lama

نموذج الاتصال