Panduan Integrasi SSO Aizu Sphere

Dokumentasi lengkap untuk mengintegrasikan Single Sign-On (SSO) Aizu Sphere ke aplikasi Anda. Tersedia contoh kode di PHP, JavaScript, Python, dan Node.js.

Daftar Isi

1. Gambaran Umum

Aizu SSO (Single Sign-On) memungkinkan aplikasi Anda untuk mengotentikasi user Aizu Sphere tanpa perlu mengelola password sendiri. User cukup login sekali di Aizu Sphere, lalu bisa mengakses semua aplikasi yang terintegrasi.

Keuntungan SSO
Mengapa menggunakan Aizu SSO?
  • Satu kali login — User login sekali, bisa akses semua aplikasi
  • Tidak perlu kelola password — Autentikasi ditangani Aizu Sphere
  • Role-based access — Dapatkan role user (Basic, Plus, Pro, family-pro, God)
  • Data user lengkap — Nama, email, foto profil, poin, dll
  • Aman — Token sekali pakai, expired 10 menit, hashed di database
  • Gratis — Tidak ada biaya untuk integrasi SSO

2. Alur SSO

Berikut alur lengkap SSO dari awal hingga user terotentikasi di aplikasi Anda:

1
User mengklik "Login dengan Aizu" di aplikasi Anda
2
Aplikasi redirect user ke https://aaizu.net/sso/ dengan parameter api_token, return, dan state
3
Jika user belum login di Aizu Sphere, mereka diarahkan ke halaman login
4
Setelah login, Aizu Sphere membuat one-time token dan redirect user ke URL callback aplikasi Anda dengan token
5
Backend aplikasi Anda mengambil token dari callback, lalu memanggil API verify_sso untuk verifikasi
6
API mengembalikan data user (user_id, username, role, email, dll). Aplikasi membuat session untuk user.
Penting: Verifikasi token HARUS dilakukan di backend (server-side), bukan di browser. Token hanya bisa digunakan sekali dan expired dalam 10 menit.

3. Prasyarat

Sebelum integrasi, Anda perlu:

  1. Terdaftar sebagai developer di Aizu Sphere
  2. Memiliki api_token dan app_key yang diberikan admin
  3. Mengatur callback_url (domain yang diizinkan untuk redirect)
  4. Memiliki backend server yang bisa menerima HTTP request
Catatan: callback_url wajib diisi di pengaturan aplikasi Anda. Jika kosong, SSO akan menolak request. Domain return URL harus sama dengan callback_url yang terdaftar.

Parameter yang Dibutuhkan

ParameterTipeKeterangan
api_token Required Token API unik untuk aplikasi Anda (diberikan admin)
return Required URL callback setelah login berhasil. Harus di domain yang terdaftar
state Optional Random string untuk CSRF protection. Dikembalikan apa adanya di response

4. Redirect ke Aizu SSO

Langkah pertama adalah mengarahkan user ke halaman SSO Aizu Sphere:

Format URL

https://aaizu.net/sso/?api_token=YOUR_API_TOKEN&return=YOUR_CALLBACK_URL&state=RANDOM_STATE

Contoh

https://aaizu.net/sso/
    ?api_token=abc123xyz789
    &return=https://myapp.com/callback
    &state=csrf_abc123_random
Tips: Generate state secara random dan simpan di session. Saat callback, pastikan state cocok untuk mencegah CSRF attack.

5. Verifikasi Token

Setelah user di-redirect kembali ke aplikasi Anda, ambil token dari URL parameter dan verifikasi via API:

Endpoint

MethodURL
GET https://aaizu.net/api/?action=verify_sso&token=SSO_TOKEN
Keamanan: Panggil endpoint ini dari backend server Anda, BUKAN dari browser/frontend. Token bersifat sensitif dan hanya boleh digunakan sekali.

6. Format Response

Response Berhasil

{
    "status": "success",
    "user_id": 123,
    "username": "johndoe",
    "role": "Pro",
    "app": "myapp",
    "state": "csrf_abc123_random",
    "nama": "John Doe",
    "email": "john@example.com",
    "foto_profil": "johndoe_abc123.jpg",
    "points": 1500,
    "jenis_kelamin": "Laki-laki",
    "tanggal_lahir": "1995-05-15"
}

Response Gagal

{
    "status": "error",
    "message": "Token tidak valid atau sudah digunakan"
}

Deskripsi Field

FieldTipeKeterangan
statusstring"success" atau "error"
user_idintID unik user di Aizu Sphere
usernamestringUsername unik user
rolestringRole efektif: Basic, Plus, Pro, family-pro, God
appstringApp key aplikasi Anda
statestringState yang Anda kirim di step 1 (untuk verifikasi CSRF)
namastringNama lengkap user
emailstringEmail user (bisa kosong)
foto_profilstringFilename foto profil. URL lengkap: https://aaizu.net/uploads/avatar/{filename}
pointsintJumlah Aizu Points user
jenis_kelaminstringLaki-laki, Perempuan, atau Lainnya
tanggal_lahirstring|nullFormat: YYYY-MM-DD atau null

7. Contoh Implementasi

PHP — Login dengan Aizu SSO

File 1: sso-login.php — Tombol login yang redirect ke Aizu SSO

<?php
// sso-login.php — Tombol "Login dengan Aizu"
// Simpan di root aplikasi Anda

session_start();

// Konfigurasi aplikasi Anda
$API_TOKEN   = 'YOUR_API_TOKEN';       // Dapat dari admin Aizu
$CALLBACK_URL = 'https://myapp.com/sso-callback.php';

// Generate random state untuk CSRF protection
$state = bin2hex(random_bytes(16));
$_SESSION['sso_state'] = $state;

// Redirect ke Aizu SSO
$sso_url = 'https://aaizu.net/sso/?' . http_build_query([
    'api_token'  => $API_TOKEN,
    'return'     => $CALLBACK_URL,
    'state'      => $state,
]);

header('Location: ' . $sso_url);
exit;

File 2: sso-callback.php — Menerima callback dan verifikasi token

<?php
// sso-callback.php — Verifikasi token SSO dari Aizu Sphere
// Simpan di root aplikasi Anda

session_start();

// 1. Ambil token dan state dari callback
$token = $_GET['token'] ?? '';
$state = $_GET['state'] ?? '';

// 2. Validasi state (CSRF protection)
if (empty($token)) {
    die('Token tidak ditemukan.');
}
if ($state !== ($_SESSION['sso_state'] ?? '')) {
    die('State tidak valid (CSRF detected).');
}
unset($_SESSION['sso_state']);

// 3. Verifikasi token ke API Aizu Sphere (dari backend!)
$api_url = 'https://aaizu.net/api/?' . http_build_query([
    'action' => 'verify_sso',
    'token'  => $token,
]);

$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

// 4. Cek hasil verifikasi
if (!$data || $data['status'] !== 'success') {
    die('Login gagal: ' . ($data['message'] ?? 'Unknown error'));
}

// 5. Simpan data user ke session aplikasi Anda
$_SESSION['aizu_user'] = [
    'user_id'     => $data['user_id'],
    'username'    => $data['username'],
    'role'        => $data['role'],
    'nama'        => $data['nama'],
    'email'       => $data['email'],
    'foto_profil' => $data['foto_profil'],
    'points'      => $data['points'],
];

// 6. Redirect ke dashboard
header('Location: /dashboard');
exit;

Node.js (Express) — Login dengan Aizu SSO

// app.js — Express SSO integration
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const session = require('express-session');

const app = express();
app.use(session({ secret: 'your-secret', resave: false, saveUninitialized: true }));

const AIZU_API_TOKEN = 'YOUR_API_TOKEN';
const CALLBACK_URL = 'https://myapp.com/auth/callback';

// Tombol login — redirect ke Aizu SSO
app.get('/auth/login', (req, res) => {
    const state = crypto.randomBytes(16).toString('hex');
    req.session.sso_state = state;

    const params = new URLSearchParams({
        api_token: AIZU_API_TOKEN,
        return: CALLBACK_URL,
        state: state,
    });

    res.redirect(`https://aaizu.net/sso/?${params}`);
});

// Callback — verifikasi token
app.get('/auth/callback', async (req, res) => {
    const { token, state } = req.query;

    if (!token) return res.status(400).send('Token tidak ditemukan');
    if (state !== req.session.sso_state) return res.status(403).send('CSRF detected');
    delete req.session.sso_state;

    try {
        const { data } = await axios.get('https://aaizu.net/api/', {
            params: { action: 'verify_sso', token }
        });

        if (data.status !== 'success') {
            return res.status(401).send(data.message);
        }

        // Simpan ke session
        req.session.user = {
            user_id: data.user_id,
            username: data.username,
            role: data.role,
            nama: data.nama,
            email: data.email,
        };

        res.redirect('/dashboard');
    } catch (err) {
        res.status(500).send('Gagal verifikasi SSO');
    }
});

app.listen(3000);

Python (Flask) — Login dengan Aizu SSO

# app.py — Flask SSO integration
from flask import Flask, redirect, request, session, jsonify
import requests, secrets

app = Flask(__name__)
app.secret_key = 'your-secret-key'

AIZU_API_TOKEN = 'YOUR_API_TOKEN'
CALLBACK_URL = 'https://myapp.com/auth/callback'

# Tombol login — redirect ke Aizu SSO
@app.route('/auth/login')
def sso_login():
    state = secrets.token_hex(16)
    session['sso_state'] = state

    params = {
        'api_token': AIZU_API_TOKEN,
        'return': CALLBACK_URL,
        'state': state,
    }
    query = '&'.join(f'{k}={v}' for k, v in params.items())
    return redirect(f'https://aaizu.net/sso/?{query}')

# Callback — verifikasi token
@app.route('/auth/callback')
def sso_callback():
    token = request.args.get('token')
    state = request.args.get('state')

    if not token:
        return 'Token tidak ditemukan', 400
    if state != session.pop('sso_state', None):
        return 'CSRF detected', 403

    # Verifikasi token ke API Aizu
    resp = requests.get('https://aaizu.net/api/', params={
        'action': 'verify_sso',
        'token': token,
    }, timeout=10)

    data = resp.json()
    if data.get('status') != 'success':
        return data.get('message', 'Login gagal'), 401

    # Simpan ke session
    session['user'] = {
        'user_id': data['user_id'],
        'username': data['username'],
        'role': data['role'],
        'nama': data['nama'],
        'email': data['email'],
    }

    return redirect('/dashboard')

if __name__ == '__main__':
    app.run(port=3000)

HTML + JavaScript — Tombol Login Sederhana

<!-- Tombol Login dengan Aizu -->
<button id="aizu-login" style="
    background: linear-gradient(135deg, #8b5cf6, #3b82f6);
    color: white;
    border: none;
    padding: 12px 24px;
    border-radius: 12px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
">
    <img src="https://aaizu.net/icon.jpg"
         width="24" height="24"
         style="border-radius: 6px;">
    Login dengan Aizu Sphere
</button>

<script>
document.getElementById('aizu-login').addEventListener('click', () => {
    const API_TOKEN = 'YOUR_API_TOKEN';
    const CALLBACK = 'https://myapp.com/sso-callback.php';
    const STATE = Math.random().toString(36).substring(2);

    // Simpan state di localStorage untuk verifikasi nanti
    localStorage.setItem('sso_state', STATE);

    // Redirect ke Aizu SSO
    window.location.href = `https://aaizu.net/sso/?api_token=${API_TOKEN}&return=${encodeURIComponent(CALLBACK)}&state=${STATE}`;
});
</script>
Peringatan: Contoh ini hanya untuk demo. Di production, verifikasi token HARUS dilakukan di backend, bukan di JavaScript browser. Jangan pernah expose API token di frontend code yang bisa diakses user.

8. Keamanan

Best Practices Keamanan

  1. Verifikasi di backend — Selalu verifikasi token dari server-side, jangan dari browser
  2. Gunakan state parameter — Generate random state, simpan di session, verifikasi saat callback
  3. Validasi response — Cek status === 'success' sebelum menggunakan data user
  4. Simpan API token aman — Jangan commit ke Git, gunakan environment variables
  5. HTTPS wajib — Callback URL harus menggunakan HTTPS
  6. Token sekali pakai — Jangan coba gunakan token yang sudah dipakai

Spesifikasi Token

PropertyValue
Format64 karakter hex (SHA-256 hash)
Masa aktif10 menit
PenggunaanSekali pakai (one-time token)
PenyimpananHashed di database (bukan plaintext)
TransportURL parameter (redirect)

9. Error Handling

Pesan ErrorPenyebabSolusi
API Token tidak valid api_token salah atau aplikasi tidak aktif Cek kembali api_token di pengaturan aplikasi
Return URL tidak diizinkan Domain return URL tidak cocok dengan callback_url Pastikan domain sama dengan yang terdaftar
Aplikasi belum mengatur callback_url callback_url kosong di database Hubungi admin untuk mengatur callback_url
Token tidak valid atau sudah digunakan Token sudah dipakai atau tidak ada Minta user login ulang
Token telah kadaluwarsa Token lebih dari 10 menit Minta user login ulang (proses lebih cepat)

10. FAQ (Pertanyaan Umum)

Apakah SSO ini gratis?

Ya, integrasi SSO Aizu Sphere sepenuhnya gratis untuk semua developer yang terdaftar.

Berapa lama token berlaku?

Token berlaku selama 10 menit setelah dibuat. Setelah itu, user harus login ulang.

Bisakah token digunakan dua kali?

Tidak. Token bersifat one-time use. Setelah diverifikasi, token langsung dihapus dari database.

Bagaimana jika user belum punya akun Aizu Sphere?

User harus mendaftar terlebih dahulu di https://aaizu.net/invite/. SSO hanya untuk user yang sudah terdaftar.

Apakah bisa mendapatkan data user tanpa SSO?

Bisa, gunakan endpoint GET https://aaizu.net/api/?action=get_user_info&user_id=ID&app_token=TOKEN. Endpoint ini wajib autentikasi —gunakan login session atau app_token dari aplikasi terdaftar.

Bagaimana cara mengecek role user?

Field role di response SSO berisi role efektif user. Nilai: Basic (gratis), Plus, Pro, family-pro, atau God (admin).

Bisakah saya membatasi akses berdasarkan role?

Ya. Saat mendaftarkan aplikasi, admin bisa mengatur allowed_roles — role yang diizinkan menggunakan SSO ke aplikasi Anda.

Butuh bantuan? Hubungi admin Aizu Sphere atau email cs@aaizu.id

© 2026 Aizu Sphere — aaizu.net