https://github.com/webexsamples/webex-flask-oauth-example
An example of authenticating an Integration with Webex using Flask with Python 3
https://github.com/webexsamples/webex-flask-oauth-example
Last synced: 8 months ago
JSON representation
An example of authenticating an Integration with Webex using Flask with Python 3
- Host: GitHub
- URL: https://github.com/webexsamples/webex-flask-oauth-example
- Owner: WebexSamples
- License: other
- Created: 2022-04-25T21:16:42.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2024-05-07T18:53:53.000Z (almost 2 years ago)
- Last Synced: 2025-04-25T03:37:17.102Z (11 months ago)
- Language: Python
- Size: 43.9 KB
- Stars: 4
- Watchers: 3
- Forks: 7
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Webex Flask OAuth Integration Sample
A comprehensive Flask application demonstrating the complete OAuth 2.0 Authorization Code flow with Webex APIs. This sample showcases secure user authentication, token management, and API integration using a clean web interface.
## đ¯ Features
This sample demonstrates how to implement OAuth 2.0 with Webex APIs using Flask:
* **OAuth 2.0 Authorization Code Flow** - Standard three-legged OAuth implementation
* **Token Management** - Access token and refresh token handling
* **Automatic Token Refresh** - Seamless handling of expired tokens
* **Webex Rooms API** - Retrieve user's room/space listings
* **Session Management** - Secure token storage with Flask sessions
* **State Parameter Validation** - CSRF protection for OAuth flow
* **Clean Web Interface** - Professional HTML templates with styling
## đ Prerequisites
### Software Requirements
- **Python 3.6 or higher**
- **Flask** web framework
- **Requests** library for HTTP operations
### Webex Developer Account
- **[Webex Developer Account](https://developer.webex.com/)** - Sign up for free
- **Webex Integration** configured for OAuth flow
## đ Quick Start
### Install Dependencies
Install the required Python modules:
```bash
pip install flask requests
```
### Create Webex Integration
1. **Navigate** to [Webex Developer Portal](https://developer.webex.com)
2. **Log in** with your Webex account
3. **Create Integration**:
- Go to **My Apps** > **Create New App** > **Integration**
- Fill in required details (name, description, icon)
- **Redirect URI**: `http://0.0.0.0:10060/oauth` (for local development)
- **Scopes**: Select `spark:all` for this sample (fine-tune for production)
4. **Save** your **Client ID** and **Client Secret**
### Setup and Configuration
1. **Update credentials** in `oauth.py` (lines 23-24):
```python
clientID = "YOUR_CLIENT_ID_HERE"
secretID = "YOUR_CLIENT_SECRET_HERE"
```
2. **Update authorization URL** in `templates/index.html`:
```html
```
**Authorization URL Format:**
```
https://webexapis.com/v1/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http://0.0.0.0:10060/oauth&scope=spark:all&state=1234abcd
```
3. **Start the application**:
```bash
python3 oauth.py
```
4. **Access the application**:
```
Listening on http://0.0.0.0:10060...
```
5. **Test the OAuth flow**:
- Open browser to `http://0.0.0.0:10060`
- Click "GRANT" to authorize
- View your Webex rooms/spaces
## đ Project Structure
```
webex-flask-oauth-example/
âââ oauth.py # Main Flask application
âââ static/css/ # CSS styling files
âââ templates/ # HTML templates
â âââ index.html # Landing page with authorization button
â âââ granted.html # Post-authorization page
â âââ spaces.html # Room/space listing display
â âââ temp.html # Base template
âââ LICENSE # Cisco Sample Code License
âââ README.md # This file
```
## đ§ Functionality Overview
### OAuth 2.0 Authorization Code Flow
| Step | Description | Implementation |
|------|-------------|----------------|
| **1. Authorization Request** | User clicks GRANT button | `index.html` with authorization URL |
| **2. User Authentication** | User logs into Webex and authorizes | External Webex authorization |
| **3. Authorization Code** | Webex redirects with auth code | `/oauth` endpoint receives code |
| **4. Token Exchange** | Exchange code for access tokens | `get_tokens()` function |
| **5. API Access** | Use tokens for authenticated requests | `spaces()` endpoint |
### Core Functions
#### Token Exchange
```python
def get_tokens(code):
url = "https://webexapis.com/v1/access_token"
payload = {
"grant_type": "authorization_code",
"client_id": clientID,
"client_secret": secretID,
"code": code,
"redirect_uri": redirectURI
}
# Exchange authorization code for tokens
```
#### Token Refresh
```python
def get_tokens_refresh():
url = "https://webexapis.com/v1/access_token"
payload = {
"grant_type": "refresh_token",
"client_id": clientID,
"client_secret": secretID,
"refresh_token": session['refresh_token']
}
# Refresh expired access token
```
#### API Calls with Token Refresh
```python
def spaces():
response = api_call()
if response.status_code == 401:
get_tokens_refresh() # Auto-refresh on token expiration
response = api_call() # Retry with new token
# Process rooms/spaces data
```
## đ Authentication Flow
### Step-by-Step Process
1. **Landing Page**: User sees "GRANT INTEGRATION ACCESS" button
2. **Authorization**: Clicking GRANT redirects to Webex authorization server
3. **User Login**: User authenticates with Webex credentials
4. **Authorization**: User approves requested scopes
5. **Callback**: Webex redirects back with authorization code
6. **Token Exchange**: App exchanges code for access and refresh tokens
7. **API Access**: User can now access their Webex data
### Security Features
- **State Parameter**: CSRF protection with hardcoded state value
- **Secure Sessions**: Tokens stored in Flask session with random secret key
- **Automatic Refresh**: Expired tokens automatically refreshed
- **Scope Validation**: OAuth scopes properly configured
## đĄ API Integration
### Webex Rooms API
The application demonstrates API integration by fetching the user's rooms:
```python
def api_call():
accessToken = session['oauth_token']
url = "https://webexapis.com/v1/rooms"
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': f'Bearer {accessToken}'
}
response = requests.get(url=url, headers=headers)
return response
```
### Error Handling
Comprehensive error handling with automatic token refresh:
```python
def spaces():
response = api_call()
# Check for unauthorized response
if response.status_code == 401:
get_tokens_refresh() # Refresh tokens
response = api_call() # Retry API call
# Process successful response
rooms = response.json()['items']
space_titles = [room['title'] for room in rooms]
return render_template("spaces.html", spaces=space_titles)
```
## đ¨ User Interface
### Flask Templates
The application uses Jinja2 templates with inheritance:
- **`temp.html`**: Base template with common styling
- **`index.html`**: Authorization page with GRANT button
- **`granted.html`**: Success page with SPACES button
- **`spaces.html`**: List of user's rooms/spaces
### Template Structure
```html
{% extends "temp.html" %}
{% block content %}
GRANT INTEGRATION ACCESS
{% endblock %}
```
### User Experience Flow
1. **Authorization Page**: Clean interface with prominent GRANT button
2. **Webex Login**: External Webex authentication
3. **Success Page**: Confirmation with SPACES button
4. **Data Display**: List of user's rooms/spaces
## đ§ Configuration
### Required Configuration Variables
| Variable | Location | Description | Example |
|----------|----------|-------------|---------|
| `clientID` | `oauth.py` line 23 | Integration Client ID | `C1234567890abcdef...` |
| `secretID` | `oauth.py` line 24 | Integration Client Secret | `secret123...` |
| `redirectURI` | `oauth.py` line 25 | OAuth callback URL | `http://0.0.0.0:10060/oauth` |
| Authorization URL | `index.html` | Webex OAuth endpoint | See format below |
### Authorization URL Format
```
https://webexapis.com/v1/authorize?
client_id=YOUR_CLIENT_ID&
response_type=code&
redirect_uri=http://0.0.0.0:10060/oauth&
scope=spark:all&
state=1234abcd
```
### Flask Application Settings
```python
app = Flask(__name__)
app.secret_key = os.urandom(24) # Secure session key
app.run("0.0.0.0", port=10060, debug=False) # Server configuration
```
## đ Production Considerations
### Security Best Practices
1. **Environment Variables**: Store credentials securely
```python
import os
clientID = os.getenv('WEBEX_CLIENT_ID')
secretID = os.getenv('WEBEX_CLIENT_SECRET')
```
2. **HTTPS**: Use HTTPS in production
```python
redirectURI = "https://yourdomain.com/oauth"
```
3. **Dynamic State**: Generate random state parameter
```python
import secrets
state = secrets.token_urlsafe(32)
```
4. **Secure Token Storage**: Use database instead of sessions
```python
# Replace Flask sessions with secure database storage
# Implement proper token encryption
```
### Production Deployment
```python
# Production configuration
if __name__ == '__main__':
port = int(os.environ.get('PORT', 10060))
app.run(host='0.0.0.0', port=port, debug=False)
```
### Error Handling Enhancement
```python
def get_tokens(code):
try:
response = requests.post(url=url, data=payload, headers=headers, timeout=30)
response.raise_for_status()
results = response.json()
# Process tokens
except requests.exceptions.RequestException as e:
logger.error(f"Token exchange failed: {e}")
# Handle error appropriately
```
## đ§ Development
### Local Development Setup
1. **Virtual Environment**:
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install flask requests
```
2. **Development Mode**:
```python
app.run("0.0.0.0", port=10060, debug=True)
```
### Adding Features
Example: Adding user profile information:
```python
@app.route("/profile")
def profile():
accessToken = session['oauth_token']
url = "https://webexapis.com/v1/people/me"
headers = {'Authorization': f'Bearer {accessToken}'}
response = requests.get(url, headers=headers)
if response.status_code == 401:
get_tokens_refresh()
response = requests.get(url, headers=headers)
user_info = response.json()
return render_template("profile.html", user=user_info)
```
### Testing the Flow
1. **Start application**: `python3 oauth.py`
2. **Open browser**: `http://0.0.0.0:10060`
3. **Click GRANT**: Initiates OAuth flow
4. **Authorize**: Log in and approve access
5. **View spaces**: See your Webex rooms/spaces
## đ Related Resources
- [Webex Developer Portal](https://developer.webex.com/)
- [OAuth 2.0 Authorization Code Flow](https://tools.ietf.org/html/rfc6749#section-4.1)
- [Webex API Documentation](https://developer.webex.com/docs/api/v1/)
- [Flask Documentation](https://flask.palletsprojects.com/)
- [Integration Management](https://developer.webex.com/my-apps)
## đ¤ Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test thoroughly with Webex integration
5. Submit a pull request
## đ License
This project is licensed under the **Cisco Sample Code License**.
### License Summary
- â
**Permitted**: Copy, modify, and redistribute for use with Cisco products
- â **Prohibited**: Use independent of Cisco products or to compete with Cisco
- âšī¸ **Warranty**: Provided "as is" without warranty
- âšī¸ **Support**: Not supported by Cisco TAC
See the [LICENSE](LICENSE) file for full license terms.
## đ Support
- Create an issue in this repository
- Visit [Webex Developer Support](https://developer.webex.com/support)
- Join the [Webex Developer Community](https://developer.webex.com/community)
---
**Ready to integrate OAuth 2.0 with Webex!** đđ