{"id":19450183,"url":"https://github.com/webexsamples/login-with-webex-flask","last_synced_at":"2026-05-12T12:05:01.319Z","repository":{"id":219361482,"uuid":"748832431","full_name":"WebexSamples/login-with-webex-flask","owner":"WebexSamples","description":"A sample flask application that implements Login With Webex, OpenID Connect, Authorization Code Flow","archived":false,"fork":false,"pushed_at":"2024-05-07T17:47:55.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-07T23:41:37.937Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WebexSamples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-26T20:49:09.000Z","updated_at":"2024-05-07T17:47:55.000Z","dependencies_parsed_at":"2024-05-07T18:44:16.096Z","dependency_job_id":"d37e5322-188a-419c-a1f0-3f38211d32c5","html_url":"https://github.com/WebexSamples/login-with-webex-flask","commit_stats":null,"previous_names":["webexsamples/login-with-webex-flask"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Flogin-with-webex-flask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Flogin-with-webex-flask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Flogin-with-webex-flask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Flogin-with-webex-flask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WebexSamples","download_url":"https://codeload.github.com/WebexSamples/login-with-webex-flask/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240637238,"owners_count":19833028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T16:35:37.331Z","updated_at":"2026-05-12T12:05:01.314Z","avatar_url":"https://github.com/WebexSamples.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Login with Webex Flask\n\nA sample Flask application that implements Login With Webex, OpenID Connect, Authorization Code Flow. This Python web application demonstrates how to integrate Webex authentication into a Flask-based web application using the standard OAuth 2.0 Authorization Code flow.\n\n## 🎯 Overview\n\nThis Flask application provides a complete implementation of the Webex OpenID Connect authentication flow, including:\n\n- **OAuth 2.0 Authorization Code Flow**: Secure server-side authentication\n- **JWT Token Parsing**: Decoding and validating ID tokens\n- **User Information Retrieval**: Accessing user profile data via the UserInfo endpoint\n- **Session Management**: Secure storage of tokens and user state\n- **Responsive Web Interface**: Clean, modern UI with Webex branding\n\n## 🔧 Dependencies\n\nThis project relies on several Python packages:\n\n- **Flask**: Web framework for Python\n- **Requests**: HTTP library for API calls\n- **JSON**: JSON parsing and manipulation (built-in)\n- **JWT**: JSON Web Token handling\n- **OS**: Operating system interface (built-in)\n- **webbrowser**: Web browser launching (built-in)\n\n## 🚀 Installation\n\nBefore you can run the project, you'll need to install the necessary dependencies. Here's how to do it:\n\n### Prerequisites\n\n1. **Python 3**: Make sure you have Python 3 installed on your machine. You can check this by running `python3 --version` in your command line. If you don't have Python installed, you can download it from [here](https://www.python.org/downloads/).\n\n2. **pip3**: Install the necessary packages using pip3. pip3 is a package manager for Python. You can install it following [these instructions](https://pip.pypa.io/en/stable/installing/).\n\n### Install Dependencies\n\nOnce you have pip3 installed, you can install the packages with the following commands:\n\n```bash\npip3 install Flask\npip3 install requests\npip3 install jwt\n```\n\n**Note**: The json and os packages are part of the Python Standard Library, so you don't need to install them separately.\n\n### Alternative: Using requirements.txt\n\nFor easier dependency management, you can create a `requirements.txt` file:\n\n```txt\nFlask==2.3.3\nrequests==2.31.0\nPyJWT==2.8.0\n```\n\nThen install with:\n```bash\npip3 install -r requirements.txt\n```\n\n## ⚙️ Configuration\n\n### 1. Webex Integration Setup\n\nBefore running the application, you need to configure your Webex Integration:\n\n1. **Go to Webex Developer Portal**: https://developer.webex.com/\n2. **Create a New Integration**: Click \"Create an Integration\"\n3. **Configure Integration Settings**:\n   - **Name**: Your application name\n   - **Description**: Brief description of your app\n   - **Redirect URI**: `http://0.0.0.0:10060/oauth`\n   - **Scopes**: `openid`, `email`, `profile` (minimum required)\n\n### 2. Application Configuration\n\nUpdate the configuration variables in `login.py`:\n\n```python\nclientID = \"YOUR CLIENT ID HERE\"  # Replace with your Integration Client ID\nsecretID = \"YOUR CLIENT SECRET HERE\"  # Replace with your Integration Client Secret\nredirectURI = \"http://0.0.0.0:10060/oauth\"  # Update if using different host/port\n```\n\n### 3. OAuth URL Configuration\n\nUpdate the OAuth URL in `templates/index.html`:\n\n```html\n\u003ca href='https://webexapis.com/v1/authorize?response_type=code\u0026client_id=YOUR_CLIENT_ID\u0026redirect_uri=http://0.0.0.0:10060/oauth\u0026scope=openid%20email%20profile\u0026state=1234abcd'\u003e\n```\n\nReplace `YOUR_CLIENT_ID` with your actual Client ID.\n\n## 🏃 Usage\n\nAfter installing the dependencies and configuring the application, you can run the script using Python in your command line:\n\n```bash\npython3 login.py\n```\n\nThe application will start and be available at:\n- **Local Access**: http://127.0.0.1:10060\n- **Network Access**: http://0.0.0.0:10060\n\n## 📁 Project Structure\n\n```\nlogin-with-webex-flask/\n├── login.py              # Main Flask application\n├── templates/            # HTML templates\n│   ├── temp.html        # Base template\n│   ├── index.html       # Login page\n│   └── user.html        # User profile page\n├── static/              # Static assets\n│   └── css/\n│       ├── index.css    # Stylesheet\n│       └── logo.png     # Webex logo\n├── LICENSE              # MIT License\n└── README.md           # This file\n```\n\n## 🔍 Application Flow\n\n### Step 1: Initial Authorization Request\n\n1. User visits the main page (`/`)\n2. User clicks the \"GRANT\" button\n3. Application redirects to Webex authorization endpoint\n4. User logs in with Webex credentials\n5. User grants permission to the application\n\n### Step 2: Authorization Code Exchange\n\n1. Webex redirects back to `/oauth` with authorization code\n2. Application validates the state parameter\n3. Application exchanges authorization code for tokens\n4. ID token and access token are stored in session\n\n### Step 3: User Information Display\n\n1. Application parses the ID token to extract claims\n2. Application calls UserInfo endpoint with access token\n3. User profile information is displayed\n\n## 🔐 Security Features\n\n### State Parameter Validation\n\nThe application uses a hardcoded state parameter (`1234abcd`) for CSRF protection:\n\n```python\nif state == '1234abcd':\n    # Process authorization code\nelse:\n    # Redirect back to login\n```\n\n### Session Management\n\nTokens are securely stored in Flask sessions:\n\n```python\nsession['id_token'] = id_token \nsession['access_token'] = access_token\n```\n\n### JWT Token Parsing\n\nID tokens are parsed without signature verification for demonstration:\n\n```python\ndef parse_jwt(token):\n    return jwt.decode(token, options={\"verify_signature\": False})\n```\n\n⚠️ **Production Note**: In production, you should validate JWT signatures.\n\n## 📊 API Endpoints\n\n### Flask Routes\n\n| Route | Method | Description |\n|-------|--------|-------------|\n| `/` | GET | Main login page |\n| `/oauth` | GET | OAuth callback handler |\n\n### Webex API Endpoints\n\n| Endpoint | Purpose |\n|----------|---------|\n| `https://webexapis.com/v1/authorize` | Authorization endpoint |\n| `https://webexapis.com/v1/access_token` | Token exchange endpoint |\n| `https://webexapis.com/v1/userinfo` | User information endpoint |\n\n## 🔧 Key Functions\n\n### `get_tokens(code)`\n\nExchanges authorization code for access and ID tokens:\n\n```python\ndef get_tokens(code):\n    url = \"https://webexapis.com/v1/access_token\"\n    headers = {'accept':'application/json','content-type':'application/x-www-form-urlencoded'}\n    payload = (\"grant_type=authorization_code\u0026client_id={0}\u0026client_secret={1}\u0026\"\n               \"code={2}\u0026redirect_uri={3}\").format(clientID, secretID, code, redirectURI)\n    req = requests.post(url=url, data=payload, headers=headers)\n    results = json.loads(req.text)\n    \n    id_token = results[\"id_token\"]\n    access_token = results[\"access_token\"]\n    session['id_token'] = id_token \n    session['access_token'] = access_token\n```\n\n### `user_info()`\n\nRetrieves user profile information:\n\n```python\ndef user_info():\n    accessToken = session['access_token']\n    url = \"https://webexapis.com/v1/userinfo\"\n    headers = {'accept': 'application/json', 'Content-Type': 'application/json',\n               'Authorization': 'Bearer ' + accessToken}\n    req = requests.get(url=url, headers=headers)\n    results = json.loads(req.text)\n    return results\n```\n\n### `parse_jwt(token)`\n\nParses JWT tokens to extract claims:\n\n```python\ndef parse_jwt(token):\n    return jwt.decode(token, options={\"verify_signature\": False})\n```\n\n## 🎨 User Interface\n\n### Design Elements\n\n- **Clean, centered layout** with Webex branding\n- **Responsive design** that works on various screen sizes\n- **Webex color scheme** (blue: #0c99d5)\n- **Professional typography** using Tahoma font\n\n### Page Components\n\n**Login Page (`index.html`)**:\n- Webex logo\n- \"GRANT INTEGRATION ACCESS\" heading\n- Large \"GRANT\" button that initiates OAuth flow\n\n**User Profile Page (`user.html`)**:\n- User claims from ID token\n- Complete user information from UserInfo endpoint\n\n## 🧪 Testing\n\n### Local Testing\n\n1. **Start the application**:\n   ```bash\n   python3 login.py\n   ```\n\n2. **Open in browser**:\n   Navigate to `http://127.0.0.1:10060`\n\n3. **Test OAuth flow**:\n   - Click \"GRANT\" button\n   - Log in with Webex credentials\n   - Verify user information is displayed\n\n### Debug Mode\n\nEnable debug mode for development:\n\n```python\napp.run(\"0.0.0.0\", port=10060, debug=True)\n```\n\nThis provides:\n- Automatic reloading on code changes\n- Detailed error messages\n- Interactive debugger\n\n## 🔍 Troubleshooting\n\n### Common Issues\n\n**Import Errors**\n```bash\nModuleNotFoundError: No module named 'flask'\n```\n*Solution*: Install missing dependencies with `pip3 install flask`\n\n**Configuration Errors**\n```\nInvalid client_id parameter\n```\n*Solution*: Verify Client ID and Secret are correctly configured\n\n**Redirect URI Mismatch**\n```\nredirect_uri_mismatch\n```\n*Solution*: Ensure redirect URI in code matches Integration settings\n\n**Token Exchange Failures**\n```\ninvalid_grant\n```\n*Solution*: Check authorization code hasn't expired (10 minutes max)\n\n### Debug Information\n\nThe application prints debug information to the console:\n\n```python\nprint(\"function : get_tokens()\")\nprint(\"code:\", code)\nprint(\"ID Token stored in session : \", session['id_token'])\nprint(\"Access Token stored in session : \", session['access_token'])\nprint('claims : ', claims)\n```\n\n## 🔒 Security Considerations\n\n### Production Deployment\n\nFor production use, consider:\n\n1. **Environment Variables**: Store secrets in environment variables\n   ```python\n   clientID = os.getenv('WEBEX_CLIENT_ID')\n   secretID = os.getenv('WEBEX_CLIENT_SECRET')\n   ```\n\n2. **HTTPS**: Use HTTPS in production\n   ```python\n   # Remove this line in production\n   os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'\n   ```\n\n3. **Secret Key**: Use a proper secret key\n   ```python\n   app.secret_key = os.getenv('FLASK_SECRET_KEY', os.urandom(24))\n   ```\n\n4. **JWT Validation**: Implement proper JWT signature validation\n   ```python\n   def parse_jwt(token):\n       # In production, validate signature\n       return jwt.decode(token, key=jwk_key, algorithms=['RS256'])\n   ```\n\n### Data Protection\n\n- **Session Security**: Uses secure session management\n- **Token Storage**: Tokens stored in server-side sessions\n- **State Validation**: CSRF protection via state parameter\n\n## 📈 Advanced Features\n\n### Custom Scopes\n\nAdd additional scopes for extended functionality:\n\n```python\n# In OAuth URL\nscope = \"openid email profile spark:people_read spark:rooms_read\"\n```\n\n### Token Refresh\n\nImplement token refresh for long-running sessions:\n\n```python\ndef refresh_token():\n    refresh_token = session.get('refresh_token')\n    # Implement refresh logic\n```\n\n### User Profile Caching\n\nCache user information to reduce API calls:\n\n```python\nfrom functools import lru_cache\n\n@lru_cache(maxsize=128)\ndef get_cached_user_info(access_token):\n    # Cached user info retrieval\n```\n\n## 🌐 Deployment\n\n### Local Development\n\n```bash\npython3 login.py\n```\n\n### Production Deployment\n\n**Using Gunicorn**:\n```bash\npip3 install gunicorn\ngunicorn -w 4 -b 0.0.0.0:10060 login:app\n```\n\n**Using Docker**:\n```dockerfile\nFROM python:3.9-slim\n\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\nCOPY . .\nEXPOSE 10060\n\nCMD [\"gunicorn\", \"-w\", \"4\", \"-b\", \"0.0.0.0:10060\", \"login:app\"]\n```\n\n### Environment Configuration\n\nCreate a `.env` file:\n```\nWEBEX_CLIENT_ID=your_client_id_here\nWEBEX_CLIENT_SECRET=your_client_secret_here\nFLASK_SECRET_KEY=your_secret_key_here\nREDIRECT_URI=https://yourdomain.com/oauth\n```\n\n## 🤝 Contributing\n\nPlease make sure to update tests as appropriate.\n\n### Development Guidelines\n\n1. **Code Style**: Follow PEP 8 Python style guidelines\n2. **Documentation**: Add docstrings for new functions\n3. **Testing**: Test OAuth flow with different user accounts\n4. **Security**: Follow security best practices for token handling\n\n### Pull Request Process\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Test thoroughly\n5. Submit a pull request with detailed description\n\n## 📄 License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n\n## 📚 Additional Resources\n\n- [Webex Developer Portal](https://developer.webex.com/)\n- [Login with Webex Documentation](https://developer.webex.com/docs/login-with-webex)\n- [OAuth 2.0 Authorization Code Flow](https://tools.ietf.org/html/rfc6749#section-4.1)\n- [OpenID Connect Specification](https://openid.net/connect/)\n- [Flask Documentation](https://flask.palletsprojects.com/)\n\n## 🔗 Related Projects\n\n- [Login with Webex (JavaScript)](https://github.com/WebexSamples/login-with-webex)\n- [Webex OAuth Integration Sample](https://github.com/WebexSamples/webex-oauth-integration)\n- [Webex Bot Framework](https://github.com/WebexCommunity/webex-node-bot-framework)\n\n## 🆘 Support\n\n- Create an issue in this repository\n- Review [Webex Developer Documentation](https://developer.webex.com/docs)\n- Contact [Webex Developer Support](https://developer.webex.com/support)\n\n---\n\n```\n                _               \n  __      _____| |__   _____  __\n  \\ \\ /\\ / / _ \\ '_ \\ / _ \\ \\/ /\n   \\ V  V /  __/ |_) |  __/\u003e  \u003c         @WebexDevs\n    \\_/\\_/ \\___|_.__/ \\___/_/\\_\\\n```\n\n**Repository**: https://github.com/WebexSamples/login-with-webex-flask\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebexsamples%2Flogin-with-webex-flask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebexsamples%2Flogin-with-webex-flask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebexsamples%2Flogin-with-webex-flask/lists"}