# Quick Start Guide Get your application integrated with this OIDC provider in 10 minutes. --- ## For the Impatient ```bash # 1. Get credentials from admin panel https://your-idp.com/admin/login # 2. Add to your app (Python example) pip install authlib flask # 3. Copy this code # (see Python example below) # 4. Done! Users can now log in via OIDC ``` --- ## Prerequisites - ✅ OIDC Provider deployed and accessible - ✅ Admin access to register your client - ✅ A web application with a backend (Node.js, Python, PHP, etc.) --- ## Step 1: Register Your Application (2 minutes) ### Via Admin Panel 1. **Navigate** to: `https://your-idp.com/admin/login` 2. **Login** with admin credentials 3. **Go to** "Clients" → "Create New Client" 4. **Fill in**: - Client Name: `My App` - Redirect URIs: `http://localhost:3000/callback` (one per line) - Allowed Scopes: `openid, profile, email` 5. **Click** "Create" 6. **Copy** your credentials: ``` Client ID: abc123def456 Client Secret: xyz789... (⚠️ save this - shown only once!) ``` --- ## Step 2: Choose Your Integration Method (1 minute) Pick the method that matches your tech stack: | If you use... | Go to | |---------------|-------| | Python + Flask | [Python Example](#python-flask) | | Node.js + Express | [Node.js Example](#nodejs-express) | | PHP + Laravel | [PHP Example](#php-laravel) | | Any other | [Generic HTTP Flow](#generic-http-flow) | --- ## Python (Flask) ### Install Dependencies ```bash pip install flask authlib requests ``` ### Code (`app.py`) ```python from flask import Flask, redirect, url_for, session, jsonify from authlib.integrations.flask_client import OAuth import os app = Flask(__name__) app.secret_key = os.urandom(24) # Configure OIDC oauth = OAuth(app) oauth.register( name='myidp', client_id='YOUR_CLIENT_ID', client_secret='YOUR_CLIENT_SECRET', server_metadata_url='https://your-idp.com/.well-known/openid-configuration', client_kwargs={'scope': 'openid profile email'} ) @app.route('/') def index(): user = session.get('user') if user: return jsonify(user) return 'Login with OIDC' @app.route('/login') def login(): redirect_uri = url_for('callback', _external=True) return oauth.myidp.authorize_redirect(redirect_uri) @app.route('/callback') def callback(): token = oauth.myidp.authorize_access_token() session['user'] = token['userinfo'] return redirect('/') @app.route('/logout') def logout(): session.pop('user', None) return redirect('/') if __name__ == '__main__': app.run(port=3000, debug=True) ``` ### Run ```bash python app.py # Open http://localhost:3000 ``` --- ## Node.js (Express) ### Install Dependencies ```bash npm install express express-session passport openid-client ``` ### Code (`server.js`) ```javascript const express = require('express'); const session = require('express-session'); const passport = require('passport'); const { Issuer, Strategy } = require('openid-client'); const app = express(); app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); passport.serializeUser((user, done) => done(null, user)); passport.deserializeUser((user, done) => done(null, user)); // Discover and configure OIDC Issuer.discover('https://your-idp.com/.well-known/openid-configuration') .then(issuer => { const client = new issuer.Client({ client_id: 'YOUR_CLIENT_ID', client_secret: 'YOUR_CLIENT_SECRET', redirect_uris: ['http://localhost:3000/callback'], response_types: ['code'], }); passport.use('oidc', new Strategy({ client }, (tokenSet, userinfo, done) => { return done(null, userinfo); })); // Routes app.get('/', (req, res) => { if (req.isAuthenticated()) { res.send(`

Hello, ${req.user.name}!

Logout`); } else { res.send('Login with OIDC'); } }); app.get('/login', passport.authenticate('oidc')); app.get('/callback', passport.authenticate('oidc', { failureRedirect: '/' }), (req, res) => res.redirect('/') ); app.get('/logout', (req, res) => { req.logout(() => res.redirect('/')); }); app.listen(3000, () => console.log('App running on http://localhost:3000')); }); ``` ### Run ```bash node server.js # Open http://localhost:3000 ``` --- ## PHP (Laravel) ### Install Socialite ```bash composer require laravel/socialite composer require socialiteproviders/oidc ``` ### Configure (`config/services.php`) ```php 'oidc' => [ 'client_id' => env('OIDC_CLIENT_ID'), 'client_secret' => env('OIDC_CLIENT_SECRET'), 'redirect' => env('OIDC_REDIRECT_URI'), 'base_url' => env('OIDC_ISSUER'), ], ``` ### Environment (`.env`) ```bash OIDC_CLIENT_ID=YOUR_CLIENT_ID OIDC_CLIENT_SECRET=YOUR_CLIENT_SECRET OIDC_REDIRECT_URI=http://localhost:8000/callback OIDC_ISSUER=https://your-idp.com ``` ### Routes (`routes/web.php`) ```php use Laravel\Socialite\Facades\Socialite; use Illuminate\Support\Facades\Auth; Route::get('/login', function () { return Socialite::driver('oidc')->redirect(); }); Route::get('/callback', function () { $user = Socialite::driver('oidc')->user(); // Find or create user in database $localUser = User::updateOrCreate( ['email' => $user->email], ['name' => $user->name] ); Auth::login($localUser); return redirect('/dashboard'); }); Route::get('/logout', function () { Auth::logout(); return redirect('/'); }); ``` ### Run ```bash php artisan serve # Open http://localhost:8000 ``` --- ## Generic HTTP Flow If you can't use a library, here's the manual flow: ### Step 1: Redirect to Authorization Endpoint ```http GET https://your-idp.com/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=http://localhost:3000/callback& response_type=code& scope=openid%20profile%20email& state=RANDOM_STATE_TOKEN ``` ### Step 2: Handle Callback User is redirected back with a code: ``` http://localhost:3000/callback?code=ABC123&state=RANDOM_STATE_TOKEN ``` **Verify state token** to prevent CSRF! ### Step 3: Exchange Code for Token ```bash curl -X POST https://your-idp.com/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=ABC123" \ -d "redirect_uri=http://localhost:3000/callback" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" ``` **Response:** ```json { "access_token": "eyJhbGci...", "id_token": "eyJhbGci...", "token_type": "Bearer", "expires_in": 3600 } ``` ### Step 4: Get User Info ```bash curl https://your-idp.com/userinfo \ -H "Authorization: Bearer ACCESS_TOKEN" ``` **Response:** ```json { "sub": "user-123", "email": "john@example.com", "name": "John Doe", "preferred_username": "john" } ``` --- ## Testing Your Integration ### 1. Start Your App ```bash # Your app should now be running on localhost ``` ### 2. Click "Login" Navigate to your app's login link. You should be redirected to: ``` https://your-idp.com/authorize?client_id=... ``` ### 3. Login Use test credentials: ``` Username: test Password: test123 ``` ### 4. Verify After login, you should: - ✅ Be redirected back to your app - ✅ See user information - ✅ Have an active session --- ## Common Issues ### "Invalid Redirect URI" **Problem**: Redirect URI doesn't match. **Fix**: 1. Check exact match (including trailing slash) 2. Update in admin panel if needed ### "Invalid Client" **Problem**: Wrong client ID or secret. **Fix**: 1. Double-check credentials 2. No extra spaces or line breaks ### "Connection Refused" **Problem**: OIDC provider not accessible. **Fix**: 1. Verify provider is running: `curl https://your-idp.com/health` 2. Check network/firewall ### CORS Errors (for SPAs) **Problem**: Browser blocks cross-origin requests. **Solution**: Don't call OIDC endpoints from frontend. Use a backend proxy. --- ## Next Steps Once basic login works: 1. **Add User Persistence**: Store user in your database 2. **Handle Logout**: Clear session and optionally redirect to IdP logout 3. **Refresh Tokens**: Implement token refresh (when available) 4. **Error Handling**: Add proper error pages 5. **Production Setup**: Use HTTPS, secure cookies --- ## Complete Examples Check out complete example applications: - **Python Flask**: `examples/python-flask/` (coming soon) - **Node.js Express**: `examples/nodejs-express/` (coming soon) - **PHP Laravel**: `examples/php-laravel/` (coming soon) --- ## Need Help? - 📖 [Full API Guide](API_GUIDE.md) - 🏗️ [Architecture](ARCHITECTURE.md) - 🚀 [Deployment](deployment.md) - 🐛 Report issues on GitHub --- **You're all set!** 🎉 Your users can now log in via OIDC in just a few clicks.