token exchange issue resolved on deployment
This commit is contained in:
parent
90d13944ec
commit
75cfd57514
216
DEPLOYMENT_CONFIGURATION.md
Normal file
216
DEPLOYMENT_CONFIGURATION.md
Normal file
@ -0,0 +1,216 @@
|
||||
# Deployment Configuration Guide
|
||||
|
||||
## Issue: Token Exchange Failing in Production
|
||||
|
||||
### Problem Description
|
||||
The OAuth token exchange is working locally but failing in production. This happens because the frontend doesn't know where the backend is deployed.
|
||||
|
||||
### Root Cause
|
||||
In `src/services/authApi.ts`:
|
||||
```typescript
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5000/api/v1';
|
||||
```
|
||||
|
||||
When `VITE_API_BASE_URL` is not set in production, it defaults to `localhost`, causing the deployed frontend to try calling a non-existent local backend.
|
||||
|
||||
### Solution: Configure Environment Variables
|
||||
|
||||
## 1. Create Environment Files
|
||||
|
||||
Create these files in the `Re_Figma_Code` directory:
|
||||
|
||||
### `.env.example` (template)
|
||||
```env
|
||||
# API Configuration
|
||||
VITE_API_BASE_URL=http://localhost:5000/api/v1
|
||||
VITE_BASE_URL=http://localhost:5000
|
||||
```
|
||||
|
||||
### `.env.local` (local development)
|
||||
```env
|
||||
VITE_API_BASE_URL=http://localhost:5000/api/v1
|
||||
VITE_BASE_URL=http://localhost:5000
|
||||
```
|
||||
|
||||
### `.env.production` (production)
|
||||
```env
|
||||
# Replace with your actual backend URL
|
||||
VITE_API_BASE_URL=https://your-backend-domain.com/api/v1
|
||||
VITE_BASE_URL=https://your-backend-domain.com
|
||||
```
|
||||
|
||||
## 2. Platform-Specific Configuration
|
||||
|
||||
### If deploying on **Vercel**:
|
||||
1. Go to your project settings
|
||||
2. Navigate to "Environment Variables"
|
||||
3. Add:
|
||||
- `VITE_API_BASE_URL` = `https://your-backend-url.com/api/v1`
|
||||
- `VITE_BASE_URL` = `https://your-backend-url.com`
|
||||
4. Select "Production" environment
|
||||
5. Redeploy
|
||||
|
||||
### If deploying on **Netlify**:
|
||||
1. Go to Site settings → Environment variables
|
||||
2. Add:
|
||||
- `VITE_API_BASE_URL` = `https://your-backend-url.com/api/v1`
|
||||
- `VITE_BASE_URL` = `https://your-backend-url.com`
|
||||
3. Redeploy the site
|
||||
|
||||
### If deploying with **Docker**:
|
||||
Add to your `docker-compose.yml` or Dockerfile:
|
||||
```yaml
|
||||
environment:
|
||||
- VITE_API_BASE_URL=https://your-backend-url.com/api/v1
|
||||
- VITE_BASE_URL=https://your-backend-url.com
|
||||
```
|
||||
|
||||
### If using **CI/CD** (GitHub Actions, etc.):
|
||||
Add to your build secrets/variables and pass them during build:
|
||||
```bash
|
||||
VITE_API_BASE_URL=https://your-backend-url.com/api/v1 npm run build
|
||||
```
|
||||
|
||||
## 3. Update .gitignore
|
||||
|
||||
Ensure `.env.local` and `.env.production` are in `.gitignore`:
|
||||
```
|
||||
# Environment files
|
||||
.env.local
|
||||
.env.production
|
||||
.env*.local
|
||||
```
|
||||
|
||||
Keep `.env.example` committed for reference.
|
||||
|
||||
## 4. OAuth Flow Validation
|
||||
|
||||
After configuring, verify the flow works:
|
||||
|
||||
### Local Flow:
|
||||
1. Frontend: `http://localhost:3000`
|
||||
2. Backend: `http://localhost:5000`
|
||||
3. Okta redirects to: `http://localhost:3000/login/callback?code=...`
|
||||
4. Frontend calls: `http://localhost:5000/api/v1/auth/token-exchange`
|
||||
5. Backend exchanges code with Okta using `redirect_uri=http://localhost:3000/login/callback`
|
||||
|
||||
### Production Flow:
|
||||
1. Frontend: `https://your-frontend.com`
|
||||
2. Backend: `https://your-backend.com`
|
||||
3. Okta redirects to: `https://your-frontend.com/login/callback?code=...`
|
||||
4. Frontend calls: `https://your-backend.com/api/v1/auth/token-exchange`
|
||||
5. Backend exchanges code with Okta using `redirect_uri=https://your-frontend.com/login/callback`
|
||||
|
||||
## 5. Update Okta Configuration
|
||||
|
||||
Ensure your Okta app has the production callback URL registered:
|
||||
|
||||
1. Log in to Okta Admin Console
|
||||
2. Go to Applications → Your App → General Settings
|
||||
3. Under "Sign-in redirect URIs", add:
|
||||
- `http://localhost:3000/login/callback` (for local dev)
|
||||
- `https://your-frontend-domain.com/login/callback` (for production)
|
||||
4. Under "Sign-out redirect URIs", add:
|
||||
- `http://localhost:3000` (for local dev)
|
||||
- `https://your-frontend-domain.com` (for production)
|
||||
5. Save changes
|
||||
|
||||
## 6. CORS Configuration
|
||||
|
||||
Ensure your backend allows requests from your production frontend:
|
||||
|
||||
In `Re_Backend/src/app.ts` or `server.ts`, update CORS:
|
||||
```typescript
|
||||
app.use(cors({
|
||||
origin: [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'https://your-frontend-domain.com' // Add your production frontend URL
|
||||
],
|
||||
credentials: true
|
||||
}));
|
||||
```
|
||||
|
||||
## 7. Testing Checklist
|
||||
|
||||
- [ ] Environment variables are set in deployment platform
|
||||
- [ ] Backend URL is reachable from frontend
|
||||
- [ ] Okta callback URLs include production URLs
|
||||
- [ ] CORS allows production frontend origin
|
||||
- [ ] Backend is deployed and running
|
||||
- [ ] Try login flow in production
|
||||
- [ ] Check browser console for API call URLs
|
||||
- [ ] Verify token exchange endpoint is being called correctly
|
||||
|
||||
## 8. Debugging
|
||||
|
||||
If still failing, check:
|
||||
|
||||
### Frontend Console:
|
||||
```javascript
|
||||
// Should show your production backend URL
|
||||
console.log('API_BASE_URL:', import.meta.env.VITE_API_BASE_URL);
|
||||
```
|
||||
|
||||
### Network Tab:
|
||||
- Look for the `/auth/token-exchange` request
|
||||
- Verify it's calling your production backend, not localhost
|
||||
- Check response status and error messages
|
||||
|
||||
### Backend Logs:
|
||||
- Check if token exchange request is reaching the backend
|
||||
- Look for Okta API errors
|
||||
- Verify redirect_uri matches what Okta expects
|
||||
|
||||
## Quick Fix Commands
|
||||
|
||||
### 1. Create environment files:
|
||||
```bash
|
||||
cd Re_Figma_Code
|
||||
|
||||
# Create .env.local
|
||||
echo "VITE_API_BASE_URL=http://localhost:5000/api/v1" > .env.local
|
||||
echo "VITE_BASE_URL=http://localhost:5000" >> .env.local
|
||||
|
||||
# Create .env.production (update URLs!)
|
||||
echo "VITE_API_BASE_URL=https://your-backend-url.com/api/v1" > .env.production
|
||||
echo "VITE_BASE_URL=https://your-backend-url.com" >> .env.production
|
||||
```
|
||||
|
||||
### 2. Test locally:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 3. Build for production:
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
The build process will use `.env.production` values.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue 1: "Network Error" or "Failed to fetch"
|
||||
**Cause**: CORS not configured or backend URL wrong
|
||||
**Fix**: Check CORS settings and verify backend URL
|
||||
|
||||
### Issue 2: "Invalid redirect_uri"
|
||||
**Cause**: Okta doesn't have production callback URL
|
||||
**Fix**: Add production URL to Okta app settings
|
||||
|
||||
### Issue 3: Still calling localhost in production
|
||||
**Cause**: Environment variable not loaded during build
|
||||
**Fix**: Ensure variables are set BEFORE building, not at runtime
|
||||
|
||||
### Issue 4: 404 on /api/v1/auth/token-exchange
|
||||
**Cause**: Wrong backend URL or backend not deployed
|
||||
**Fix**: Verify backend is running and URL is correct
|
||||
|
||||
## Notes
|
||||
|
||||
- Vite environment variables MUST start with `VITE_` to be exposed to client
|
||||
- Environment variables are embedded at **build time**, not runtime
|
||||
- Changing env vars requires rebuilding the frontend
|
||||
- Never commit `.env.local` or `.env.production` with real URLs to git
|
||||
|
||||
97
setup-env.bat
Normal file
97
setup-env.bat
Normal file
@ -0,0 +1,97 @@
|
||||
@echo off
|
||||
REM Environment Setup Script for Royal Enfield Workflow Frontend (Windows)
|
||||
|
||||
echo ==================================================
|
||||
echo Royal Enfield - Frontend Environment Setup
|
||||
echo ==================================================
|
||||
echo.
|
||||
|
||||
echo This script will create environment configuration files for your frontend.
|
||||
echo.
|
||||
|
||||
REM Check if files already exist
|
||||
if exist ".env.local" (
|
||||
echo WARNING: .env.local already exists
|
||||
set FILE_EXISTS=1
|
||||
)
|
||||
if exist ".env.production" (
|
||||
echo WARNING: .env.production already exists
|
||||
set FILE_EXISTS=1
|
||||
)
|
||||
|
||||
if defined FILE_EXISTS (
|
||||
echo.
|
||||
set /p OVERWRITE="Do you want to OVERWRITE existing files? (y/n): "
|
||||
if /i not "%OVERWRITE%"=="y" (
|
||||
echo Aborted. No files were modified.
|
||||
exit /b 0
|
||||
)
|
||||
)
|
||||
|
||||
REM Create .env.example
|
||||
echo # API Configuration> .env.example
|
||||
echo # Backend API base URL (with /api/v1)>> .env.example
|
||||
echo VITE_API_BASE_URL=http://localhost:5000/api/v1>> .env.example
|
||||
echo.>> .env.example
|
||||
echo # Base URL for direct file access (without /api/v1)>> .env.example
|
||||
echo VITE_BASE_URL=http://localhost:5000>> .env.example
|
||||
echo Created .env.example
|
||||
|
||||
REM Create .env.local
|
||||
echo # Local Development Environment> .env.local
|
||||
echo VITE_API_BASE_URL=http://localhost:5000/api/v1>> .env.local
|
||||
echo VITE_BASE_URL=http://localhost:5000>> .env.local
|
||||
echo Created .env.local (for local development)
|
||||
|
||||
REM Create .env.production
|
||||
echo.
|
||||
echo ==================================================
|
||||
echo Production Environment Configuration
|
||||
echo ==================================================
|
||||
echo.
|
||||
set /p BACKEND_URL="Enter your PRODUCTION backend URL (e.g., https://api.yourcompany.com): "
|
||||
|
||||
if "%BACKEND_URL%"=="" (
|
||||
echo WARNING: No backend URL provided. Creating template file...
|
||||
echo # Production Environment> .env.production
|
||||
echo # IMPORTANT: Update these URLs with your actual deployed backend URL>> .env.production
|
||||
echo VITE_API_BASE_URL=https://your-backend-url.com/api/v1>> .env.production
|
||||
echo VITE_BASE_URL=https://your-backend-url.com>> .env.production
|
||||
) else (
|
||||
REM Remove trailing slash if present
|
||||
if "%BACKEND_URL:~-1%"=="/" set BACKEND_URL=%BACKEND_URL:~0,-1%
|
||||
|
||||
echo # Production Environment> .env.production
|
||||
echo VITE_API_BASE_URL=%BACKEND_URL%/api/v1>> .env.production
|
||||
echo VITE_BASE_URL=%BACKEND_URL%>> .env.production
|
||||
echo Created .env.production with backend URL: %BACKEND_URL%
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ==================================================
|
||||
echo Setup Complete!
|
||||
echo ==================================================
|
||||
echo.
|
||||
echo Next Steps:
|
||||
echo.
|
||||
echo 1. For LOCAL development:
|
||||
echo npm run dev
|
||||
echo (will use .env.local automatically)
|
||||
echo.
|
||||
echo 2. For PRODUCTION deployment:
|
||||
echo - If deploying to Vercel/Netlify/etc:
|
||||
echo Set environment variables in your platform dashboard
|
||||
echo - If using Docker/VM:
|
||||
echo Ensure .env.production has correct URLs
|
||||
echo.
|
||||
echo 3. Update Okta Configuration:
|
||||
echo - Add production callback URL to Okta app settings
|
||||
echo - Sign-in redirect URI: https://your-frontend.com/login/callback
|
||||
echo.
|
||||
echo 4. Update Backend CORS:
|
||||
echo - Add production frontend URL to CORS allowed origins
|
||||
echo.
|
||||
echo For detailed instructions, see: DEPLOYMENT_CONFIGURATION.md
|
||||
echo.
|
||||
pause
|
||||
|
||||
111
setup-env.sh
Normal file
111
setup-env.sh
Normal file
@ -0,0 +1,111 @@
|
||||
#!/bin/bash
|
||||
# Environment Setup Script for Royal Enfield Workflow Frontend
|
||||
|
||||
echo "=================================================="
|
||||
echo "Royal Enfield - Frontend Environment Setup"
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
|
||||
# Function to create .env.example
|
||||
create_env_example() {
|
||||
cat > .env.example << 'EOF'
|
||||
# API Configuration
|
||||
# Backend API base URL (with /api/v1)
|
||||
VITE_API_BASE_URL=http://localhost:5000/api/v1
|
||||
|
||||
# Base URL for direct file access (without /api/v1)
|
||||
VITE_BASE_URL=http://localhost:5000
|
||||
EOF
|
||||
echo "✅ Created .env.example"
|
||||
}
|
||||
|
||||
# Function to create .env.local
|
||||
create_env_local() {
|
||||
cat > .env.local << 'EOF'
|
||||
# Local Development Environment
|
||||
VITE_API_BASE_URL=http://localhost:5000/api/v1
|
||||
VITE_BASE_URL=http://localhost:5000
|
||||
EOF
|
||||
echo "✅ Created .env.local (for local development)"
|
||||
}
|
||||
|
||||
# Function to create .env.production template
|
||||
create_env_production() {
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo "Production Environment Configuration"
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
read -p "Enter your PRODUCTION backend URL (e.g., https://api.yourcompany.com): " BACKEND_URL
|
||||
|
||||
if [ -z "$BACKEND_URL" ]; then
|
||||
echo "⚠️ No backend URL provided. Creating template file..."
|
||||
cat > .env.production << 'EOF'
|
||||
# Production Environment
|
||||
# IMPORTANT: Update these URLs with your actual deployed backend URL
|
||||
VITE_API_BASE_URL=https://your-backend-url.com/api/v1
|
||||
VITE_BASE_URL=https://your-backend-url.com
|
||||
EOF
|
||||
else
|
||||
# Remove trailing slash if present
|
||||
BACKEND_URL=${BACKEND_URL%/}
|
||||
|
||||
cat > .env.production << EOF
|
||||
# Production Environment
|
||||
VITE_API_BASE_URL=${BACKEND_URL}/api/v1
|
||||
VITE_BASE_URL=${BACKEND_URL}
|
||||
EOF
|
||||
echo "✅ Created .env.production with backend URL: ${BACKEND_URL}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
echo "This script will create environment configuration files for your frontend."
|
||||
echo ""
|
||||
|
||||
# Check if files already exist
|
||||
if [ -f ".env.local" ] || [ -f ".env.production" ]; then
|
||||
echo "⚠️ Environment files already exist:"
|
||||
[ -f ".env.local" ] && echo " - .env.local"
|
||||
[ -f ".env.production" ] && echo " - .env.production"
|
||||
echo ""
|
||||
read -p "Do you want to OVERWRITE them? (y/n): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Aborted. No files were modified."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create files
|
||||
create_env_example
|
||||
create_env_local
|
||||
create_env_production
|
||||
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo "✅ Setup Complete!"
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
echo "Next Steps:"
|
||||
echo ""
|
||||
echo "1. For LOCAL development:"
|
||||
echo " npm run dev"
|
||||
echo " (will use .env.local automatically)"
|
||||
echo ""
|
||||
echo "2. For PRODUCTION deployment:"
|
||||
echo " - If deploying to Vercel/Netlify/etc:"
|
||||
echo " Set environment variables in your platform dashboard"
|
||||
echo " - If using Docker/VM:"
|
||||
echo " Ensure .env.production has correct URLs"
|
||||
echo ""
|
||||
echo "3. Update Okta Configuration:"
|
||||
echo " - Add production callback URL to Okta app settings"
|
||||
echo " - Sign-in redirect URI: https://your-frontend.com/login/callback"
|
||||
echo ""
|
||||
echo "4. Update Backend CORS:"
|
||||
echo " - Add production frontend URL to CORS allowed origins"
|
||||
echo ""
|
||||
echo "📖 For detailed instructions, see: DEPLOYMENT_CONFIGURATION.md"
|
||||
echo ""
|
||||
|
||||
@ -577,14 +577,14 @@ function Auth0ContextWrapper({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Auth Provider - conditionally uses backend or Auth0
|
||||
* Main Auth Provider - uses backend for token exchange in all environments
|
||||
* Backend handles Okta token exchange securely with client secret
|
||||
*/
|
||||
export function AuthProvider({ children }: AuthProviderProps) {
|
||||
if (isLocalhost()) {
|
||||
// Always use BackendAuthProvider so backend handles token exchange
|
||||
// This keeps the client secret secure on the server
|
||||
return <BackendAuthProvider>{children}</BackendAuthProvider>;
|
||||
}
|
||||
return <Auth0AuthProvider>{children}</Auth0AuthProvider>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to use auth context
|
||||
|
||||
Loading…
Reference in New Issue
Block a user