๐Ÿ” Solving Vimeo API Authentication: Building a Secure Video Gallery with OAuth 2.0

saqibsaqib
8 min read

๐Ÿšจ The Problem: Vimeo API Authentication Nightmare

The Error That Started It All

Vimeo API Error: Can't upload video - "No user credentials were provided." or "No user credentials were provided" when you try to Retrieve Videos from your account!

When I tried to integrate Vimeo's API into my project, I hit a wall. The official documentation was confusing, and I kept getting authentication errors despite following their guides. The problem? There was no clear solution for OAuth 2.0 implementation in the Vimeo documentation.

What I Discovered

  • Client Credentials Grant doesn't work for user-specific data

  • OAuth 2.0 flow was poorly documented

  • Token generation required manual API calls

  • Error handling was vague and unhelpful

  • No working examples for web applications

๐Ÿ’ก The Solution: Built-In OAuth 2.0 with Token Generator

Instead of struggling with unclear documentation, I built a complete solution that includes:

  1. OAuth 2.0 Authentication Flow - Proper implementation

  2. Built-in Token Generator - No more manual API calls

  3. Secure Video Gallery - Display videos without exposing credentials

  4. Comprehensive Error Handling - Clear solutions for common issues.

๐Ÿ—๏ธ Project Architecture

Technology Stack

  • Frontend: Next.js 14 + React 18 + TypeScript

  • Styling: Tailwind CSS for responsive design

  • Authentication: OAuth 2.0 (Authorization Code Grant)

  • API: Vimeo REST API v3.4

  • HTTP Client: Axios for API requests.

Key Components


src/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ api/vimeo/
โ”‚   โ”‚   โ”œโ”€โ”€ videos/         # Fetch user videos
โ”‚   โ”‚   โ””โ”€โ”€ token/          # OAuth token exchange
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ VimeoGallery.tsx   # Video display
โ”‚   โ”‚   โ””โ”€โ”€ SimpleVimeoTest.tsx # Token generator
โ”‚   โ”œโ”€โ”€ lib/
โ”‚   โ”‚   โ””โ”€โ”€ vimeo.ts       # Vimeo API service
โ”‚   โ””โ”€โ”€ types/
โ”‚       โ””โ”€โ”€ vimeo.ts       # TypeScript definitions

๐Ÿ”‘ The OAuth 2.0 Solution

Why OAuth 2.0 Instead of API Keys?

โŒ API Keys (Client Credentials)

  • Only work for app-level data

  • Can't access user-specific content

  • Limited scope and permissions

  • Security risks if exposed

โœ… OAuth 2.0 (Authorization Code Grant)

  • User-specific access tokens

  • Secure, industry-standard protocol

  • Users can revoke access anytime

  • Proper scope control

The Complete OAuth Flow

Step 1: App Registration

  1. Create Vimeo app with "User Authentication" type

  2. Set redirect URI: http://localhost:3000/api/auth/vimeo/callback

  3. Configure scopes: public, private (avoid video_files for free accounts).

Step 2: Authorization Request

const authUrl = `https://api.vimeo.com/oauth/authorize
?response_type=code
&client_id=${CLIENT_ID}
&redirect_uri=${REDIRECT_URI}
&scope=public private`;

Step 3: Token Exchange

// Exchange authorization code for access token
const response = await fetch('https://api.vimeo.com/oauth/access_token', {
  method: 'POST',
  headers: {
    'Authorization': `Basic ${btoa(CLIENT_ID + ':' + CLIENT_SECRET)}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    redirect_uri: REDIRECT_URI
  })
});

๐Ÿ› ๏ธ Built-in Token Generator: The Game Changer

The Problem with Manual Token Generation

  • Complex API calls required

  • Authorization codes expire in 5-10 minutes

  • No visual feedback during the process

  • Error handling was difficult.

My Solution: SimpleVimeoTest Component

I built a user-friendly interface that handles the entire OAuth flow:

export default function SimpleVimeoTest() {
  const [authCode, setAuthCode] = useState('');
  const [accessToken, setAccessToken] = useState('');
  const [userInfo, setUserInfo] = useState<any>(null);

  const handleGetToken = async () => {
    // Exchange authorization code for access token
    const response = await fetch('/api/vimeo/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ code: authCode.trim() })
    });

    const data = await response.json();
    if (data.success) {
      setAccessToken(data.access_token);
      setUserInfo(data.user);
    }
  };

  // ... rest of component with UI
}

Features of the Token Generator

  • Step-by-step guidance for OAuth flow

  • Authorization code input with validation

  • Automatic token exchange via API

  • Connection testing to verify tokens work

  • User info display for verification

  • Clear error messages and solutions.

๐Ÿ”ง API Implementation

Token Exchange Endpoint

// /api/vimeo/token/route.ts
export async function POST(request: NextRequest) {
  try {
    const { code } = await request.json();

    const tokenResponse = await fetch('https://api.vimeo.com/oauth/access_token', {
      method: 'POST',
      headers: {
        'Authorization': `Basic ${Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`,
        'Content-Type': 'application/json',
        'Accept': 'application/vnd.vimeo.*+json;version=3.4'
      },
      body: JSON.stringify({
        grant_type: 'authorization_code',
        code: code,
        redirect_uri: REDIRECT_URI
      })
    });

    const tokenData = await tokenResponse.json();

    return NextResponse.json({
      success: true,
      access_token: tokenData.access_token,
      user: tokenData.user
    });
  } catch (error) {
    return NextResponse.json({ error: 'Token exchange failed' }, { status: 500 });
  }
}

Video Fetching Service

// /lib/vimeo.ts
export default class VimeoService {
  private accessToken: string;

  constructor(accessToken?: string) {
    this.accessToken = accessToken || process.env.VIMEO_ACCESS_TOKEN || '';
  }

  async getUserVideos(page = 1, per_page = 25) {
    const response = await axios.get('https://api.vimeo.com/me/videos', {
      headers: this.getHeaders(),
      params: { page, per_page }
    });
    return response.data;
  }

  private getHeaders() {
    return {
      'Authorization': `Bearer ${this.accessToken}`,
      'Accept': 'application/vnd.vimeo.*+json;version=3.4'
    };
  }
}

Responsive Grid Layout

export default function VimeoGallery() {
  const [videos, setVideos] = useState<VimeoVideo[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchVideos();
  }, []);

  const fetchVideos = async () => {
    const response = await fetch('/api/vimeo/videos');
    const data = await response.json();

    if (data.success) {
      setVideos(data.videos || []);
    }
  };

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
      {videos.map((video) => (
        <VideoCard key={video.uri} video={video} />
      ))}
    </div>
  );
}

Video Player Modal

const VideoModal = ({ video, onClose }) => (
  <div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center">
    <div className="bg-white rounded-lg max-w-4xl w-full">
      <iframe
        src={`https://player.vimeo.com/video/${video.uri.split('/').pop()}`}
        width="100%"
        height="400"
        allow="autoplay; fullscreen"
        allowFullScreen
      />
      {/* Video details and metadata */}
    </div>
  </div>
);

๐Ÿšจ Solving Common Authentication Issues

Issue 1: "Invalid authorization code"

Problem: Authorization codes expire quickly and can only be used once Solution: Get fresh codes and use immediately via the built-in token generator

Issue 2: "App didn't receive user credentials"

Problem: Using wrong authentication method Solution: Ensure app type is "User Authentication" and use OAuth flow

Issue 3: "Video files scope requires paid plan"

Problem: Requesting premium scopes on free accounts Solution: Use only public and private scopes

Issue 4: "401 Unauthorized"

Problem: Expired or invalid access tokens Solution: Generate new OAuth tokens using the token generator


๐Ÿ”’ Security Features

OAuth 2.0 Security

  • State parameter prevents CSRF attacks

  • HTTPS required for production

  • Scope limitation requests minimal permissions

  • Token expiration handled gracefully

Development Security

  • Environment variables for sensitive data

  • Never commit tokens to version control

  • Separate tokens for different environments

  • Access control limits token exposure


๐Ÿ“ฑ User Experience Features

Built-in Token Generator

  • Visual workflow with color-coded sections

  • Real-time feedback during token generation

  • Error handling with clear solutions

  • Connection testing before committing tokens

  • Responsive design works on all devices

  • Modal player for seamless video viewing

  • Video metadata display (duration, date, plays)

  • Loading states and error handling


๐Ÿš€ Deployment and Production

Environment Configuration

# Development
VIMEO_CLIENT_ID=your_dev_client_id
VIMEO_CLIENT_SECRET=your_dev_client_secret
VIMEO_REDIRECT_URI=http://localhost:3000/api/auth/vimeo/callback
VIMEO_ACCESS_TOKEN=your_dev_token

# Production
VIMEO_CLIENT_ID=your_prod_client_id
VIMEO_CLIENT_SECRET=your_prod_client_secret
VIMEO_REDIRECT_URI=https://yourdomain.com/api/auth/vimeo/callback
VIMEO_ACCESS_TOKEN=your_prod_token

Production Considerations

  • HTTPS required for OAuth 2.0

  • Environment variables in hosting platform

  • Token monitoring for expiration

  • Error tracking for debugging


๐Ÿ“Š Results and Impact

What This Project Achieved

  1. Solved the authentication problem that wasn't documented

  2. Created a user-friendly OAuth flow with visual guidance

  3. Built a secure video gallery without exposing credentials

  4. Provided comprehensive documentation for future developers

Technical Benefits

  • Secure authentication using industry standards

  • Built-in token management eliminates manual work

  • Responsive design works on all devices

  • Error handling provides clear solutions

Developer Experience

  • No more authentication headaches with Vimeo API

  • Clear documentation for OAuth implementation

  • Working examples for common use cases

  • Reusable components for other projects


๐Ÿ”ฎ Future Enhancements

Planned Features

  • Search and filtering for videos

  • Advanced pagination with infinite scroll

  • Custom video player with analytics

  • Video categories and organization

  • User management for multiple accounts

Potential Applications

  • Portfolio websites for video creators

  • Educational platforms with video content

  • Corporate video libraries for internal use

  • E-commerce with product videos

  • Social platforms with video sharing


๐Ÿ“š Lessons Learned

OAuth 2.0 Implementation

  • Authorization Code Grant is the right choice for web apps

  • State parameters are essential for security

  • Token expiration must be handled gracefully

  • Scope limitation improves security

API Integration

  • Clear error messages are crucial for debugging

  • Built-in tools improve developer experience

  • Comprehensive documentation saves time

  • Working examples are invaluable

Project Development

  • Solve real problems that others face

  • Build tools that make development easier

  • Document everything for future reference

  • Focus on user experience from the start


๐ŸŽฏ Conclusion

This project started as a solution to a frustrating Vimeo API authentication problem and evolved into a comprehensive video gallery application. By implementing OAuth 2.0 properly and building a user-friendly token generator, I created a solution that:

  1. Solves the authentication problem that wasn't clearly documented

  2. Provides a secure way to display Vimeo videos

  3. Offers a better developer experience with built-in tools

  4. Demonstrates best practices for OAuth 2.0 implementation

The key insight was that instead of struggling with unclear documentation, I could build a complete solution that handles the entire OAuth flow seamlessly. The built-in token generator eliminates the need for manual API calls and provides clear guidance for users.

This approach not only solved my immediate problem but also created a reusable solution that others can benefit from. The project demonstrates that sometimes the best solution is to build the tools you need rather than waiting for better documentation.



This project demonstrates that with the right approach, even complex authentication problems can be solved elegantly. By building tools that make OAuth 2.0 accessible and user-friendly, we can create better developer experiences and more secure applications.

0
Subscribe to my newsletter

Read articles from saqib directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

saqib
saqib

As a Web3 Software Engineer and the founder of Orbimatrix, I empowers businesses to thrive in the decentralized future. He's an expert in crafting innovative blockchain and AI solutions that don't just innovate, but deliver tangible value: think streamlined operations and boosted ROI. Discover how Web3 and AI can revolutionize your business. Orbimatrix provides strategic guidance, custom software development, and complete solution integration, all designed to meet your unique needs and ensure your success.