Laravel SSO client for LifeWind authentication
lifewind/laravel-sso-client is a Laravel package for laravel sso client for lifewind authentication.
It currently has 0 GitHub stars and 0 downloads on Packagist (latest version v1.0.0).
Install it with composer require lifewind/laravel-sso-client.
Discover more Laravel packages by lifewind
or browse all Laravel packages to compare alternatives.
Last updated
API-only SSO authentication for Laravel backends.
This package provides secure JWT-based authentication endpoints for validating OAuth tokens from frontend applications.
Before installing this package, you need an OAuth client registered in LifeWind Core:
https://lifewind-core.test/admin (or your production URL)https://your-app.com/sso/callback).envTip: For local development, use
http://localhost:3001/sso/callbackas the redirect URI (adjust port to match your frontend dev server).
composer require lifewind/laravel-sso-client
Publish configuration and run migrations:
php artisan vendor:publish --provider="LifeWind\SSO\SSOServiceProvider"
php artisan migrate
# LifeWind SSO Configuration
LIFEWIND_SSO_BASE_URL=https://lifewind-core.your-domain.com
LIFEWIND_SSO_CLIENT_ID=your_oauth_client_id
LIFEWIND_SSO_CLIENT_SECRET=your_oauth_client_secret
LIFEWIND_SSO_REDIRECT_URI=https://your-frontend.com/sso/callback
LIFEWIND_SSO_CREATE_USERS=true
LIFEWIND_SSO_UPDATE_USERS=true
# JWT Configuration
LIFEWIND_SSO_JWT_SECRET=your-256-bit-secret-key
LIFEWIND_SSO_JWT_EXPIRY=86400
Update config/cors.php:
return [
'paths' => ['api/*', 'sso/*'],
'allowed_origins' => ['https://your-frontend.com'],
'allowed_headers' => ['*'],
'allowed_methods' => ['*'],
'supports_credentials' => false, // JWT in Authorization header
];
The package automatically registers these endpoints:
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | /sso/validate | Validate OAuth code β return JWT + user |
| GET | /sso/user | Get authenticated user (Bearer token) |
| POST | /sso/refresh | Refresh JWT token |
Exchange OAuth authorization code for JWT token.
Request:
{
"code": "oauth_authorization_code_from_callback",
"state": "oauth_state_parameter",
"redirect_uri": "https://your-frontend.com/sso/callback"
}
Success Response (200):
{
"success": true,
"user": {
"id": 1,
"email": "[email protected]",
"name": "John Doe",
"lifewind_uuid": "550e8400-e29b-41d4-a716-446655440000"
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expires_in": 86400
}
Error Response (400):
{
"success": false,
"error": "Token validation failed: Invalid authorization code"
}
Get current authenticated user information.
Headers:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Accept: application/json
Success Response (200):
{
"authenticated": true,
"local_user": {
"id": 1,
"email": "[email protected]",
"name": "John Doe",
"lifewind_uuid": "550e8400-e29b-41d4-a716-446655440000"
},
"authenticated_via": "jwt",
"token_expiry": "2024-01-15T14:30:00.000Z"
}
Error Response (401):
{
"error": "Invalid or expired authentication token",
"authenticated": false
}
Refresh an existing JWT token.
Headers:
Authorization: Bearer current_jwt_token
Accept: application/json
Success Response (200):
{
"success": true,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expires_in": 86400,
"token_expiry": "2024-01-16T14:30:00.000Z"
}
Use the built-in middleware to protect your API routes:
// routes/api.php
Route::middleware(['lifewind.auth'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::apiResource('projects', ProjectController::class);
Route::get('/profile', [UserController::class, 'profile']);
});
Access the authenticated user in your controllers:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class DashboardController extends Controller
{
public function index(Request $request): JsonResponse
{
// The middleware ensures this user is authenticated
$user = $request->user(); // Returns User model instance
return response()->json([
'message' => "Welcome {$user->name}!",
'user' => [
'id' => $user->id,
'email' => $user->email,
'name' => $user->name,
'lifewind_uuid' => $user->lifewind_uuid,
],
'dashboard_data' => [
'recent_activity' => '...',
'notifications' => '...'
]
]);
}
}
If you're using a custom User model:
// config/lifewind-sso.php
'user' => [
'model' => App\Models\CustomUser::class,
'create' => true,
'update' => true,
'fields' => [
'email' => 'email',
'name' => 'name',
'lifewind_uuid' => 'lifewind_uuid',
],
],
# JWT Settings
LIFEWIND_SSO_JWT_SECRET=your-super-secure-256-bit-secret-key
LIFEWIND_SSO_JWT_EXPIRY=86400 # 24 hours in seconds
LIFEWIND_SSO_JWT_ALGORITHM=HS256 # Signing algorithm
# Request specific scopes from LifeWind
LIFEWIND_SSO_SCOPES="openid,profile,email,roles"
# User creation/update behavior
LIFEWIND_SSO_CREATE_USERS=true # Create new users automatically
LIFEWIND_SSO_UPDATE_USERS=true # Update existing users from SSO data
# Test SSO configuration
php artisan sso:test
# Test with detailed output
php artisan sso:test --verbose
# Test specific environment
php artisan sso:test --env=staging
Test the endpoints manually:
# 1. Test validation endpoint
curl -X POST https://your-backend.com/sso/validate \
-H "Content-Type: application/json" \
-d '{
"code": "test_auth_code",
"state": "test_state",
"redirect_uri": "https://your-frontend.com/sso/callback"
}'
# 2. Test user endpoint with returned token
curl -X GET https://your-backend.com/sso/user \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"
This package is designed for frontend-initiated OAuth flows:
/sso/validate endpointUse our companion Vue.js package:
npm install lifewind-vue-sso-client
<template>
<LifeWindSSOButton
@success="handleAuth"
button-text="Login with LifeWind"
/>
</template>
<script setup>
import { LifeWindSSOButton } from 'lifewind-vue-sso-client'
const handleAuth = (result) => {
console.log('Authenticated:', result.user)
// Token automatically stored, ready for API calls
}
</script>
Implement the OAuth flow manually:
// 1. Redirect to OAuth provider
const authUrl = `https://lifewind-core.com/oauth/authorize?` +
`client_id=YOUR_CLIENT_ID&` +
`redirect_uri=${encodeURIComponent('https://your-frontend.com/callback')}&` +
`response_type=code&` +
`state=${generateRandomState()}&` +
`scope=openid profile email`
window.location.href = authUrl
// 2. Handle callback (in your callback page)
const urlParams = new URLSearchParams(window.location.search)
const code = urlParams.get('code')
const state = urlParams.get('state')
// 3. Validate with your backend
const response = await fetch('https://your-backend.com/sso/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code,
state,
redirect_uri: 'https://your-frontend.com/callback'
})
})
const result = await response.json()
if (result.success) {
// Store JWT token for API requests
localStorage.setItem('auth_token', result.token)
localStorage.setItem('user', JSON.stringify(result.user))
}
# Production Environment
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.your-domain.com
# LifeWind SSO (Production)
LIFEWIND_SSO_BASE_URL=https://sso.lifewind.com
LIFEWIND_SSO_CLIENT_ID=prod_client_id_here
LIFEWIND_SSO_CLIENT_SECRET=prod_client_secret_here
LIFEWIND_SSO_REDIRECT_URI=https://app.your-domain.com/sso/callback
LIFEWIND_SSO_JWT_SECRET=your-production-256-bit-secret-key
LIFEWIND_SSO_VERIFY_SSL=true
# Remove all localhost/development origins from CORS!
// config/lifewind-sso.php
'cache' => [
'user_data' => true, // Cache user data lookups
'ttl' => 300, // 5 minutes
],
'rate_limiting' => [
'validate' => '10,1', // 10 requests per minute
'user' => '60,1', // 60 requests per minute
'refresh' => '5,1', // 5 requests per minute
],
"Invalid authorization code" error:
LIFEWIND_SSO_REDIRECT_URI matches exactly what you registeredredirect_uri sent to /sso/validate matches OAuth registrationCORS errors:
config/cors.phpAccess-Control-Allow-Credentials is properly configuredJWT token invalid:
LIFEWIND_SSO_JWT_SECRET is the same across all app instancesexpires_in seconds)Authorization: Bearer <token>Enable detailed logging in development:
LOG_LEVEL=debug
LIFEWIND_SSO_DEBUG=true
Check logs at:
tail -f storage/logs/laravel.log | grep SSO
MIT License. See LICENSE for details.
Built for modern API-first applications π