JWT yang diterbitkan dazoapp adalah kontrak lintas-service. Frontend memakainya untuk mengakses backend Go dan seluruh microservice lain. Ini bukan auth internal.
Ringkasan alur
ISSUE:
Login (password / Google SSO / QuickLogin admin)
→ auth('api')->attempt() / login() / JWTAuth::fromUser()
→ Tymon generate JWT dengan claim standar (sub, iat, exp, nbf, iss, jti, prv)
→ claim custom = KOSONG (tidak ada store_id/role di token)
→ response: { access_token, expires_in: 3600, user }
REFRESH:
POST /api/refresh (Authorization: Bearer <old token>)
→ auth('api')->refresh(true, true)
→ old token di-blacklist (tidak bisa dipakai lagi)
→ new token di-issue (TTL sama: 60 menit)
→ response: { access_token, expires_in }
CROSS-SERVICE:
Frontend → backend Go (url_api) pakai axios polos
→ Authorization: Bearer <token> (TAPI axios polos tidak auto-attach)
→ backend Go verifikasi pakai secret bersama JWT_SECRET1. Token issuance
Titik penerbitan
| Titik | Lokasi | Metode |
|---|---|---|
| Login utama | app/Services/AuthService.php:143 | auth('api')->attempt($credentials) |
| Refresh token | app/Services/AuthService.php:181 | auth('api')->refresh(true, true) |
| Quick login admin | app/Http/Controllers/QuickLoginController.php:53 | JWTAuth::fromUser($user) |
| Save store (onboarding) | app/Http/Controllers/WelcomeController.php:607 | auth('api')->login($user) |
| Google SSO | app/Http/Controllers/Auth/GoogleAuthController.php:165 | auth('api')->login($user) |
Claim/payload
Claim standar (config/jwt.php:149-156):
sub— user ID (MongoDB UUID string) dariUser::getJWTIdentifier()(User.php:60-63)iat,exp,nbf,iss,jti— standar Tymonprv— otomatis aktif (config/jwt.php:193lock_subject = true) untuk mencegah cross-model impersonation
TTL
| Token | TTL | Sumber |
|---|---|---|
| Access token | 60 menit | config/jwt.php:104 — env('JWT_TTL', 60) |
| Refresh window | 10.000 menit (~6,9 hari) | config/jwt.php:124 — env('JWT_REFRESH_TTL', 10000) |
expires_in di response = auth('api')->factory()->getTTL() * 60 (detik) — AuthService.php:160.
Secret
config/jwt.php:28 — 'secret' => env('JWT_SECRET'). Algoritma HS256 (config/jwt.php:136).
2. Refresh flow
Endpoint
POST /api/refresh (routes/api.php:85) → AuthController@refresh (AuthController.php:35-38) → AuthService::refresh() (AuthService.php:178-196).
Verifikasi & rotation
- Tymon verifikasi signature +
expdari token lama - Token lama harus masih dalam window
refresh_ttl(10.000 menit) sejakiatasli auth('api')->refresh(true, true)(AuthService.php:181):- Argumen 1
forceBlacklist=true— token lama di-blacklist, tidak bisa dipakai lagi - Argumen 2
blacklistEmulate=true— emulate blacklist behavior
- Argumen 1
- Blacklist aktif (
config/jwt.php:222JWT_BLACKLIST_ENABLED=true), storage default cache Illuminate (config/jwt.php:299)
Token expired saat request
Tymon lempar TokenExpiredException. Di AuthService.php:191-195 catch jadi AuthenticationException (401). Frontend axiosInstance.js:46:
- POST
/api/refreshpakai access token lama di header Authorization - Simpan access token baru ke
localStorage - Replay request
- Kalau refresh gagal,
localStorage.clear()+router.post('/logout')(axiosInstance.js:74-76)
3. Cross-service usage
Service yang memakai JWT dazoapp
| Service | URL config | Cara pakai |
|---|---|---|
Backend Go (url_api) | resources/js/global.js:66-86 | Frontend call langsung pakai axios polos (lihat SchedularCreate.vue:1342, PenjadwalanBroadcastTab.vue:806) |
Engine WhatsApp (url_engine) | global.js | Tidak ada auth token — endpoint bersifat terbuka, hanya instance ID. Dipanggil dari backend Laravel via cURL (DeviceService.php:33) |
Engine Bot (url_ai_agent) | global.js | Dipanggil dari sisi Go, bukan langsung dari dazoapp |
Cara frontend kirim token
Authorization: Bearer {token} header. resources/js/services/axiosInstance.js:12-22 — interceptor request ambil localStorage.getItem('access_token'), set header Authorization.
Token exchange vs langsung
Frontend memanggil backend Go (url_api) langsung pakai JWT dazoapp lewat axios. Tidak ada token exchange.
URL service di frontend
| Env | url_engine | url_api | url_ai_agent |
|---|---|---|---|
| local | http://localhost:5002/ | http://127.0.0.1:8081/v1/ | http://127.0.0.1:1212/ |
| development | https://engine.dazo.dev/ | https://api.dazo.dev/v1/ | https://engine-bot.dazo.dev/ |
| production | https://engine.dazo.id/ | https://api.dazo.id/v1/ | https://engine-bot.dazo.id/ |
4. Guard & middleware
Guard
Guard api dengan driver jwt — config/auth.php:43-46. Provider users = Eloquent App\Models\User (config/auth.php:67-70).
User model implement Tymon\JWTAuth\Contracts\JWTSubject (User.php:11,15).
Middleware
auth:apiHANYA dipakai di 1 route group:routes/api.php:86-89(/testjwt,/logout)- Mayoritas route API pakai
auth:sanctum(sanctum stateful via session cookie, bukan JWT) - Tidak ada middleware alias
jwt.auth/jwt.verifyterdaftar diapp/Http/Kernel.php:59-75. Tymon default dimasukkan viaauth:apiguard driver
Scope/role check
user_store pivot di-load saat auth
Eager loading: Auth::user()->loadMissing(['store', 'user_store.store']) — pola dominan (HandleInertiaRequests.php:52, BroadcastchatController.php:517, dst). Relasi User->user_store() = belongsTo(UserStore, 'id', 'user_id') (User.php:45-48). Bukan dari JWT, tapi query DB setelah auth resolve.
Inkonsistensi host engine WA
| Lokasi | Host |
|---|---|
resources/js/global.js (production) | engine.dazo.id |
app/Services/DeviceService.php:17 | engine-wa.dazo.id |
app/Http/Controllers/BroadcastscedularController.php:37 | engine-wa.dazo.id |
app/Http/Controllers/AgentAiController.php:38 | engine-wa.dazo.id |
| Controller lain (Downgrade, LoginlogController, OrderController) | engine.dazo.id |
Jangan pilih sendiri — butuh konfirmasi user. Lihat External Services.
Yang tidak boleh diubah sendiri
Referensi file
| File | Peran |
|---|---|
app/Services/AuthService.php | Issue + refresh token |
app/Http/Controllers/Api/AuthController.php | Endpoint refresh |
app/Http/Controllers/QuickLoginController.php | Quick login admin (login-as-user) |
app/Models/User.php | JWTSubject implementation |
config/jwt.php | TTL, secret, blacklist config |
config/auth.php | Guard api driver jwt |
resources/js/services/axiosInstance.js | Auto-refresh token frontend |
resources/js/global.js | URL service (url_api, url_engine, url_ai_agent) |