Dokumentasi API

Panduan lengkap untuk mengintegrasikan aplikasi Anda dengan SSO DPUPR Provinsi Banten.

Base URL

https://sso.dpupr.com

Autentikasi

SSO DPUPR menggunakan protokol OAuth 2.0 dengan PKCE (Proof Key for Code Exchange) untuk autentikasi yang aman. Setiap aplikasi client harus terdaftar untuk mendapatkan Client ID & Secret.

Grant Type Penggunaan
authorization_code Aplikasi web dengan backend
authorization_code + PKCE SPA, Mobile App (recommended)
refresh_token Memperbarui access token

OAuth Flow

Alur autentikasi Authorization Code dengan PKCE:

1

Generate PKCE

Buat code_verifier (random string) dan code_challenge (SHA256 hash)

2

Redirect ke Authorization

Redirect user ke /oauth/authorize dengan parameters

3

User Login

User login dan approve akses

4

Exchange Code

Tukar authorization_code + code_verifier untuk access token

OAuth Endpoints

GET /oauth/authorize

Authorization endpoint - redirect user kesini untuk login

Parameters
client_id Client ID aplikasi Anda
redirect_uri URL callback setelah login
response_type code
scope Scope yang diminta (space-separated)
state Random string untuk CSRF protection
code_challenge PKCE code challenge (SHA256)
POST /oauth/token

Token endpoint - tukar code dengan access token

Request Body
"grant_type": "authorization_code",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"redirect_uri": "https://your-app.com/callback",
"code": "authorization-code",
"code_verifier": "your-code-verifier"

Scopes

Scope menentukan akses yang diberikan ke aplikasi:

Scope Deskripsi
read-profile Membaca profil dasar user
bina-marga Akses untuk Bidang Bina Marga
sumber-daya-air Akses untuk Bidang Sumber Daya Air
cipta-karya Akses untuk Bidang Cipta Karya
tata-ruang Akses untuk Bidang Tata Ruang

User Profile API

GET /api/user

Mendapatkan profil lengkap user yang sedang login

Headers
Authorization: Bearer {access_token}
Accept: application/json
Response
{
  "id": 1,
  "nip": "199001012020121001",
  "nama": "John Doe",
  "email": "john@dpupr.bantenprov.go.id",
  "no_hp": "081234567890",
  "is_active": true,
  "bidang": {
    "id": 1,
    "kode": "BM",
    "nama": "Bidang Bina Marga"
  },
  "jabatan": {
    "id": 5,
    "nama": "Staff"
  },
  "roles": ["user"],
  "permissions": ["users.view"],
  "scopes": ["bina-marga", "read-profile"]
}

Logout API

POST /api/logout

Logout dari sesi saat ini (revoke current token)

POST /api/logout-all

Single Sign-Out: Logout dari SEMUA aplikasi sekaligus (revoke all tokens)

Integrasi Laravel Socialite

Contoh integrasi dengan Laravel Socialite:

1. Install Package

composer require laravel/socialite

2. Konfigurasi config/services.php

'dpupr_sso' => [
    'client_id' => env('DPUPR_SSO_CLIENT_ID'),
    'client_secret' => env('DPUPR_SSO_CLIENT_SECRET'),
    'redirect' => env('DPUPR_SSO_REDIRECT_URI'),
    'host' => 'https://sso.dpupr.com',
],

3. Controller

public function redirect()
{
    return Socialite::driver('dpupr_sso')->redirect();
}

public function callback()
{
    $user = Socialite::driver('dpupr_sso')->user();
    // Login user...
}

Integrasi React / Vue (SPA)

Penting: Aplikasi SPA (Single Page Application) berjalan di browser yang dianggap "Public Client". Jangan pernah menyimpan client_secret di kode frontend. Gunakan PKCE Flow.

1. Install Library Client

Disarankan menggunakan library yang menangani PKCE secara otomatis, contohnya react-oauth2-code-pkce.

npm install react-oauth2-code-pkce

2. Konfigurasi AuthProvider

import { AuthProvider } from 'react-oauth2-code-pkce';

const authConfig = {
  clientId: 'your-client-id',
  authorizationEndpoint: 'https://sso.dpupr.com/oauth/authorize',
  tokenEndpoint: 'https://sso.dpupr.com/oauth/token',
  redirectUri: 'http://localhost:3000/callback',
  scope: 'read-profile bina-marga',
  onRefreshTokenExpire: (event) => window.confirm('Session expired. Login again?'),
};

function App() {
  return (
    <AuthProvider authConfig={authConfig}>
       <YourApp />
    </AuthProvider>
  );
}

3. Menggunakan Token untuk API Request

import { useContext } from 'react';
import { AuthContext } from 'react-oauth2-code-pkce';

const UserProfile = () => {
  const { token } = useContext(AuthContext);

  const fetchProfile = async () => {
    const response = await fetch('https://sso.dpupr.com/api/user', {
      headers: {
        Authorization: `Bearer ${token}`
      }
    });
    const data = await response.json();
    console.log(data);
  };
  
  // ...
}

Integrasi Node.js (Express)

Untuk aplikasi backend Node.js, Anda bisa menggunakan flow Authorization Code standar dengan client_secret.

1. Setup Route Login

const axios = require('axios');
const express = require('express');
const app = express();

const SSO_CONFIG = {
  client_id: 'your-id',
  client_secret: 'your-secret',
  redirect_uri: 'http://localhost:3000/callback'
};

// 1. Redirect ke SSO
app.get('/login/sso', (req, res) => {
  const url = `https://sso.dpupr.com/oauth/authorize?client_id=${SSO_CONFIG.client_id}&redirect_uri=${SSO_CONFIG.redirect_uri}&response_type=code&scope=read-profile`;
  res.redirect(url);
});

2. Handle Callback

// 2. Callback untuk tukar code jadi token
app.get('/callback', async (req, res) => {
  const { code } = req.query;

  try {
    // Request Token
    const tokenParams = {
      grant_type: 'authorization_code',
      client_id: SSO_CONFIG.client_id,
      client_secret: SSO_CONFIG.client_secret,
      redirect_uri: SSO_CONFIG.redirect_uri,
      code: code
    };

    const { data: tokenData } = await axios.post('https://sso.dpupr.com/oauth/token', tokenParams);
    const accessToken = tokenData.access_token;

    // Ambil User Info
    const { data: userData } = await axios.get('https://sso.dpupr.com/api/user', {
      headers: { Authorization: `Bearer ${accessToken}` }
    });

    res.json({ user: userData, token: accessToken });

  } catch (error) {
    res.status(500).json({ error: 'Login failed' });
  }
});

Integrasi PHP Native

Contoh implementasi tanpa framework menggunakan cURL standard.

1. Konfigurasi (files: config.php)

<?php
define('SSO_CLIENT_ID', 'your-client-id');
define('SSO_CLIENT_SECRET', 'your-client-secret');
define('SSO_REDIRECT_URI', 'http://localhost/app/callback.php');
define('SSO_HOST', 'https://sso.dpupr.com'); // URL SSO Server
?>

2. Redirect ke Login (files: login.php)

<?php
require 'config.php';

$query = http_build_query([
    'client_id' => SSO_CLIENT_ID,
    'redirect_uri' => SSO_REDIRECT_URI,
    'response_type' => 'code',
    'scope' => 'read-profile',
    'state' => bin2hex(random_bytes(16)) // CSRF Protection
]);

header("Location: " . SSO_HOST . "/oauth/authorize?" . $query);
exit;
?>

3. Handle Callback (files: callback.php)

<?php
require 'config.php';
session_start();

if (!isset($_GET['code'])) {
    die("Error: Authorization code not found");
}

// 1. Tukar Code jadi Token via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, SSO_HOST . "/oauth/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'grant_type' => 'authorization_code',
    'client_id' => SSO_CLIENT_ID,
    'client_secret' => SSO_CLIENT_SECRET,
    'redirect_uri' => SSO_REDIRECT_URI,
    'code' => $_GET['code'],
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200) {
    die("Error exchanging token: " . $response);
}

$tokenData = json_decode($response, true);
$accessToken = $tokenData['access_token'];

// 2. Ambil Profil User
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, SSO_HOST . "/api/user");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $accessToken",
    "Accept: application/json"
]);

$userResponse = curl_exec($ch);
curl_close($ch);

$userProfile = json_decode($userResponse, true);

// 3. Simpan di Session Login
$_SESSION['user'] = $userProfile;
$_SESSION['token'] = $accessToken;

header("Location: dashboard.php");
exit;
?>

Integrasi Mobile App (Flutter/React Native)

Aplikasi Mobile menggunakan PKCE Flow dan Deep Linking (Custom URL Scheme).

1

Deep Link / App Scheme

Pastikan aplikasi mobile Anda mendaftarkan Custom URL Scheme, misalnya dpuprapp://callback. Daftarkan URL ini juga di Admin SSO > OAuth Clients.

2

Web Browser Session

Gunakan WebBrowser atau SafariViewController/ChromeCustomTabs untuk membuka halaman login SSO. Jangan gunakan WebView embedded karena alasan keamanan.

Contoh Flow (React Native - Expo AuthSession)

import * as AuthSession from 'expo-auth-session';

const discovery = {
  authorizationEndpoint: 'https://sso.dpupr.com/oauth/authorize',
  tokenEndpoint: 'https://sso.dpupr.com/oauth/token',
};

// ... inside component
const [request, response, promptAsync] = AuthSession.useAuthRequest(
  {
    clientId: 'your-mobile-client-id',
    redirectUri: 'exp://localhost:19000/--/callback', // Expo Dev Client
    scopes: ['read-profile'],
    usePKCE: true, // Wajib ON
  },
  discovery
);

React.useEffect(() => {
  if (response?.type === 'success') {
    const { code } = response.params;
    // Exchange code for token...
  }
}, [response]);

Error Handling

Status Error Deskripsi
401 unauthenticated Token tidak valid atau expired
403 insufficient_scope Token tidak memiliki scope yang diperlukan
403 account_disabled Akun user dinonaktifkan
400 invalid_request Parameter request tidak valid