WamISSO Documentation

Vue.js + Laravel API

Split your app into a Vue SPA frontend and a Laravel API backend. Laravel handles OAuth with WamISSO; Vue consumes authenticated API routes via Sanctum session cookies or API tokens.

Before you start: Complete developer registration and create an OAuth client. Register two redirect URIs if needed: http://localhost:5173/auth/callback (Vue) or handle callback on the API at http://localhost:8001/api/auth/sso/callback.

Recommended architecture

Laravel API setup

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
# API .env
SSO_BASE_URL=https://wamisso.rendovations.com
SSO_CLIENT_ID=your-client-id
SSO_CLIENT_SECRET=your-client-secret
SSO_REDIRECT_URI=http://localhost:8001/api/auth/sso/callback
FRONTEND_URL=http://localhost:5173
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DOMAIN=localhost

API routes

// routes/api.php
use App\Http\Controllers\Api\SsoAuthController;

Route::prefix('auth/sso')->group(function () {
    Route::get('/redirect', [SsoAuthController::class, 'redirect']);
    Route::get('/callback', [SsoAuthController::class, 'callback']);
});

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn (Request $request) => $request->user());
    Route::post('/logout', [SsoAuthController::class, 'logout']);
});

SSO auth controller

// app/Http/Controllers/Api/SsoAuthController.php
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class SsoAuthController extends Controller
{
    public function redirect(): JsonResponse
    {
        $state = Str::random(40);
        session(['oauth_state' => $state]);

        $query = http_build_query([
            'client_id'     => config('services.wamisso.client_id'),
            'redirect_uri'  => config('services.wamisso.redirect'),
            'response_type' => 'code',
            'scope'         => 'openid profile email',
            'state'         => $state,
        ]);

        return response()->json([
            'authorize_url' => config('services.wamisso.base_url').'/oauth/authorize?'.$query,
        ]);
    }

    public function callback(Request $request): RedirectResponse
    {
        if ($request->query('state') !== session('oauth_state')) {
            abort(403, 'Invalid OAuth state');
        }

        session()->forget('oauth_state');

        $tokens = Http::asForm()
            ->post(config('services.wamisso.base_url').'/oauth/token', [
                'grant_type'    => 'authorization_code',
                'client_id'     => config('services.wamisso.client_id'),
                'client_secret' => config('services.wamisso.client_secret'),
                'redirect_uri'  => config('services.wamisso.redirect'),
                'code'          => $request->query('code'),
            ])
            ->throw()
            ->json();

        $profile = Http::withToken($tokens['access_token'])
            ->get(config('services.wamisso.base_url').'/api/user')
            ->throw()
            ->json();

        $user = User::query()->updateOrCreate(
            ['email' => $profile['email']],
            ['name' => $profile['name'] ?? $profile['email']],
        );

        Auth::login($user);

        return redirect(config('app.frontend_url', env('FRONTEND_URL')).'/dashboard');
    }

    public function logout(Request $request): JsonResponse
    {
        $accessToken = session('sso_access_token');

        if ($accessToken) {
            Http::withToken($accessToken)
                ->post(config('services.wamisso.base_url').'/api/sso/logout');
        }

        Auth::guard('web')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return response()->json(['status' => 'logged_out']);
    }
}

CORS and Sanctum

// config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'supports_credentials' => true,
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:5173')],

Vue login composable

// src/composables/useAuth.js
import axios from 'axios';

axios.defaults.withCredentials = true;
axios.defaults.baseURL = import.meta.env.VITE_API_URL; // http://localhost:8001

export async function loginWithSso() {
  await axios.get('/sanctum/csrf-cookie');
  const { data } = await axios.get('/api/auth/sso/redirect');
  window.location.href = data.authorize_url;
}

export async function fetchUser() {
  const { data } = await axios.get('/api/user');
  return data;
}

export async function logout() {
  await axios.post('/api/logout');
}

Vue login page

<script setup>
import { loginWithSso } from '@/composables/useAuth';
</script>

<template>
  <div class="login">
    <h1>Sign in</h1>
    <button type="button" @click="loginWithSso">
      Continue with WamISSO
    </button>
  </div>
</template>
Enable withCredentials on Axios/fetch so Sanctum session cookies work across your Vue app and Laravel API during local development.