Skip to content

Exemplos de Implementação

Esta seção contém exemplos práticos de implementação do fluxo de autenticação OAuth 2.0 em diferentes linguagens e frameworks.

JavaScript (Frontend)

Exemplo Completo

javascript
const CLIENT_ID = 'seu_client_id';
const REDIRECT_URI = 'https://seu-dominio.com.br/callback';
const LOGIN_BASE_URL = '{login-producao}';
const SECURITY_BASE_URL = '{security-producao}';

function gerarState() {
  return btoa(Math.random().toString()).substring(0, 16);
}

function iniciarLogin() {
  const state = gerarState();
  sessionStorage.setItem('oauth_state', state);
  
  const authUrl = `${LOGIN_BASE_URL}/authorize?response_type=code&scope=openid profile&client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&state=${state}`;
  
  window.location.href = authUrl;
}

async function trocarCodigoPorToken(code) {
  const response = await fetch(`${SECURITY_BASE_URL}/api/token/v2`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: CLIENT_ID,
      client_secret: 'seu_client_secret',
      code: code
    })
  });

  if (!response.ok) {
    throw new Error('Erro ao trocar código por tokens');
  }

  return await response.json();
}

function processarCallback() {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  const error = urlParams.get('error');
  const state = urlParams.get('state');
  const storedState = sessionStorage.getItem('oauth_state');

  if (error) {
    console.error('Erro na autenticação:', error);
    return;
  }

  if (state !== storedState) {
    console.error('State não corresponde');
    return;
  }

  if (code) {
    trocarCodigoPorToken(code)
      .then(tokens => {
        console.log('Tokens recebidos:', tokens);
        validarEUsarTokens(tokens);
      })
      .catch(error => {
        console.error('Erro:', error);
      });
  }
}

Node.js (Backend)

Exemplo com Express

javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

const CLIENT_ID = 'seu_client_id';
const CLIENT_SECRET = 'seu_client_secret';
const REDIRECT_URI = 'https://seu-dominio.com.br/callback';
const LOGIN_BASE_URL = '{login-producao}';
const SECURITY_BASE_URL = '{security-producao}';

app.get('/login', (req, res) => {
  const state = require('crypto').randomBytes(16).toString('hex');
  req.session.oauthState = state;
  
  const authUrl = `${LOGIN_BASE_URL}/authorize?response_type=code&scope=openid profile&client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&state=${state}`;
  
  res.redirect(authUrl);
});

app.get('/callback', async (req, res) => {
  const { code, error, state } = req.query;

  if (error) {
    return res.status(400).send(`Erro: ${error}`);
  }

  if (state !== req.session.oauthState) {
    return res.status(400).send('State inválido');
  }

  try {
    const tokenResponse = await fetch(`${SECURITY_BASE_URL}/api/token/v2`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        code: code
      })
    });

    const tokens = await tokenResponse.json();

    const decoded = jwt.verify(tokens.id_token, CLIENT_SECRET, {
      issuer: 'fanbase',
      audience: CLIENT_ID
    });

    req.session.user = decoded;
    res.redirect('/dashboard');
  } catch (error) {
    res.status(500).send(`Erro: ${error.message}`);
  }
});

app.get('/userinfo', async (req, res) => {
  const accessToken = req.session.tokens?.access_token;
  
  if (!accessToken) {
    return res.status(401).send('Não autenticado');
  }

  try {
    const response = await fetch(`${SECURITY_BASE_URL}/api/userinfo`, {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });

    const userInfo = await response.json();
    res.json(userInfo);
  } catch (error) {
    res.status(500).send(`Erro: ${error.message}`);
  }
});

Python

Exemplo com Flask

python
from flask import Flask, redirect, request, session
import requests
import jwt
import secrets

app = Flask(__name__)
app.secret_key = 'sua_chave_secreta'

CLIENT_ID = 'seu_client_id'
CLIENT_SECRET = 'seu_client_secret'
REDIRECT_URI = 'https://seu-dominio.com.br/callback'
LOGIN_BASE_URL = '{login-producao}'
SECURITY_BASE_URL = '{security-producao}'

@app.route('/login')
def login():
    state = secrets.token_urlsafe(16)
    session['oauth_state'] = state
    
    auth_url = f'{LOGIN_BASE_URL}/authorize?response_type=code&scope=openid profile&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&state={state}'
    
    return redirect(auth_url)

@app.route('/callback')
def callback():
    code = request.args.get('code')
    error = request.args.get('error')
    state = request.args.get('state')
    
    if error:
        return f'Erro: {error}', 400
    
    if state != session.get('oauth_state'):
        return 'State inválido', 400
    
    token_data = {
        'grant_type': 'authorization_code',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'code': code
    }
    
    response = requests.post(
        f'{SECURITY_BASE_URL}/api/token/v2',
        data=token_data
    )
    
    tokens = response.json()
    
    try:
        decoded = jwt.decode(
            tokens['id_token'],
            CLIENT_SECRET,
            issuer='fanbase',
            audience=CLIENT_ID,
            algorithms=['HS256']
        )
        session['user'] = decoded
        session['tokens'] = tokens
        return redirect('/dashboard')
    except jwt.InvalidTokenError as e:
        return f'Token inválido: {e}', 400

@app.route('/userinfo')
def userinfo():
    access_token = session.get('tokens', {}).get('access_token')
    
    if not access_token:
        return 'Não autenticado', 401
    
    headers = {'Authorization': f'Bearer {access_token}'}
    response = requests.get(f'{SECURITY_BASE_URL}/api/userinfo', headers=headers)
    
    return response.json()

PHP

Exemplo Básico

php
<?php
session_start();

define('CLIENT_ID', 'seu_client_id');
define('CLIENT_SECRET', 'seu_client_secret');
define('REDIRECT_URI', 'https://seu-dominio.com.br/callback');
define('LOGIN_BASE_URL', '{login-producao}');
define('SECURITY_BASE_URL', '{security-producao}');

function iniciarLogin() {
    $state = bin2hex(random_bytes(16));
    $_SESSION['oauth_state'] = $state;
    
    $authUrl = LOGIN_BASE_URL . '/authorize?' . http_build_query([
        'response_type' => 'code',
        'scope' => 'openid profile',
        'client_id' => CLIENT_ID,
        'redirect_uri' => REDIRECT_URI,
        'state' => $state
    ]);
    
    header('Location: ' . $authUrl);
    exit;
}

function processarCallback() {
    $code = $_GET['code'] ?? null;
    $error = $_GET['error'] ?? null;
    $state = $_GET['state'] ?? null;
    
    if ($error) {
        die('Erro: ' . $error);
    }
    
    if ($state !== $_SESSION['oauth_state']) {
        die('State inválido');
    }
    
    $ch = curl_init(SECURITY_BASE_URL . '/api/token/v2');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
        'grant_type' => 'authorization_code',
        'client_id' => CLIENT_ID,
        'client_secret' => CLIENT_SECRET,
        'code' => $code
    ]));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $tokens = json_decode($response, true);
    
    $_SESSION['tokens'] = $tokens;
    
    return $tokens;
}

function obterUserInfo($accessToken) {
    $ch = curl_init(SECURITY_BASE_URL . '/api/userinfo');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $accessToken
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    return json_decode($response, true);
}
?>

Obter Token com Client Credentials (Para Integrações Connect)

JavaScript

javascript
async function obterTokenClientCredentials() {
  const CLIENT_ID = 'seu_client_id';
  const CLIENT_SECRET = 'seu_client_secret';
  const SECURITY_BASE_URL = '{security-producao}';

  const params = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET
  });

  const response = await fetch(`${SECURITY_BASE_URL}/api/token?${params}`, {
    method: 'POST'
  });

  if (!response.ok) {
    throw new Error('Erro ao obter token');
  }

  const data = await response.json();
  return data.access_token;
}

Node.js

javascript
async function obterTokenConnect() {
  const CLIENT_ID = 'seu_client_id';
  const CLIENT_SECRET = 'seu_client_secret';
  const SECURITY_BASE_URL = '{security-producao}';

  const params = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET
  });

  const response = await fetch(`${SECURITY_BASE_URL}/api/token?${params}`, {
    method: 'POST'
  });

  const data = await response.json();
  return data.access_token;
}

Usar API Connect

Exemplo: Criar Objeto na Fila

javascript
async function criarObjetoFila(accessToken) {
  const CONNECT_BASE_URL = '{connect-producao}';

  const response = await fetch(`${CONNECT_BASE_URL}/api/v1/integration/queue`, {
    method: 'POST',
    headers: {
      'AccessToken': accessToken,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      action: 'ticket-create',
      data: {
        dados_do_ingresso: 'valor',
        dados_do_comprador: 'valor'
      }
    })
  });

  if (!response.ok) {
    throw new Error('Erro ao criar objeto na fila');
  }

  return await response.json();
}

Exemplo: Obter Profile Completo

javascript
async function obterProfile(clientId, jwtToken) {
  const SECURITY_BASE_URL = '{security-producao}';

  const response = await fetch(`${SECURITY_BASE_URL}/api/profile/${clientId}`, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${jwtToken}`
    }
  });

  if (!response.ok) {
    throw new Error('Erro ao obter perfil');
  }

  const resultado = await response.json();
  
  if (resultado.header.codigo !== 1) {
    throw new Error(resultado.header.msg);
  }

  return resultado.data;
}

Recursos Adicionais

Documentação da API Fanbase