vsyncDOCUMENTAÇÃO

Recursos de Plataforma

Entrar com vsync (OAuth2)

Deixe pessoas entrarem no seu site ou app com a conta vsync: fluxo Authorization Code com PKCE, endpoints, escopos e exemplos.

Com Entrar com vsync o seu site ou app identifica uma pessoa pela conta dela no vsync, sem pedir senha. É o fluxo OAuth2 Authorization Code, com PKCE opcional. Qualquer desenvolvedor pode usar: basta ter um aplicativo no Portal do Desenvolvedor.

Como funciona#

  1. Seu site manda a pessoa para https://vsync.lat/oauth2/authorize com client_id, redirect_uri, scope e state.
  2. O vsync pede login (se preciso) e mostra a tela de consentimento, com o nome do app, o que ele vai acessar e o domínio de destino.
  3. Se a pessoa clicar em Autorizar, ela volta para a sua redirect_uri com ?code=...&state=.... Se clicar em Cancelar, volta com ?error=access_denied&state=....
  4. O servidor do seu site troca o code por um access_token em POST https://api.vsync.lat/oauth2/token.
  5. Com o access_token você chama GET https://api.vsync.lat/oauth2/userinfo e cria a sessão da pessoa no seu site.

Configurar o aplicativo#

No Portal do Desenvolvedor, abra o aplicativo e vá na aba OAuth2:

  • Client ID: é o id do aplicativo.
  • Client Secret: clique em Gerar secret. Ele aparece uma única vez e só o hash fica guardado conosco; redefinir invalida o antigo na hora. Use só no servidor, nunca em código que roda no navegador ou no celular.
  • Redirect URIs: até 10 endereços. A comparação é exata (caminho, query e barra final contam). Só https://; o http:// é aceito apenas para o endereço local de desenvolvimento 127.0.0.1. Fragmentos (#) e usuário/senha na URL não são permitidos. Nunca redirecionamos para um endereço que não esteja na lista.
  • Gerador de link: monta o link de autorização com os escopos que você marcar.

Escopos#

EscopoO que libera
identifyGET /oauth2/userinfo e GET /oauth2/@me com id, usuário, nome de exibição e avatar
emailInclui email e verified no userinfo. Precisa vir junto com identify
guildsGET /oauth2/guilds: servidores da pessoa, com ícone e as permissões dela

Separe os escopos por espaço. Um escopo desconhecido faz o pedido falhar com invalid_scope. O escopo bot não pode ser misturado com estes.

Texto
https://vsync.lat/oauth2/authorize?client_id=ID_DO_APP&response_type=code&redirect_uri=https%3A%2F%2Fseusite.com%2Fauth%2Fcallback&scope=identify%20email&state=VALOR_ALEATORIO&code_challenge=DESAFIO&code_challenge_method=S256
ParâmetroObrigatórioDescrição
client_idsimId do aplicativo
redirect_urisimUma das redirect URIs cadastradas, idêntica
scopesimEscopos separados por espaço
response_typenãoSe enviado, deve ser code
staterecomendadoValor aleatório que você guarda e confere na volta (proteção contra CSRF)
code_challengerecomendadoPKCE: SHA-256 do code_verifier, em base64url (43 caracteres)
code_challenge_methodcom PKCESempre S256

O código tem 5 minutos de validade e só pode ser usado uma vez.

PKCE#

PKCE protege o código mesmo que alguém o intercepte, e permite apps sem servidor (sem secret). Gere um code_verifier aleatório por login, mande o code_challenge no passo 1 e o code_verifier no passo 2:

JavaScript
import { createHash, randomBytes } from "node:crypto";

const verifier = randomBytes(32).toString("base64url");
const challenge = createHash("sha256").update(verifier).digest("base64url");

Se o pedido de autorização levou um code_challenge, a troca exige o code_verifier correto, mesmo com client_secret. Sem client_secret, a troca só é aceita com PKCE.

Passo 2: trocar o código por token#

POST https://api.vsync.lat/oauth2/token, em application/x-www-form-urlencoded ou JSON. A autenticação do cliente vai por client_id e client_secret no corpo, ou por HTTP Basic (client_id:client_secret).

Bash
curl -X POST https://api.vsync.lat/oauth2/token \
  -d grant_type=authorization_code \
  -d code=CODIGO_RECEBIDO \
  -d redirect_uri=https://seusite.com/auth/callback \
  -d client_id=ID_DO_APP \
  -d client_secret=SECRET_DO_APP \
  -d code_verifier=VERIFIER
JavaScript
const res = await fetch("https://api.vsync.lat/oauth2/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code,
    redirect_uri: "https://seusite.com/auth/callback",
    client_id: process.env.VSYNC_CLIENT_ID,
    client_secret: process.env.VSYNC_CLIENT_SECRET,
    code_verifier: verifier,
  }),
});
const tokens = await res.json();

Resposta:

JSON
{
  "access_token": "vsat_...",
  "token_type": "Bearer",
  "expires_in": 604800,
  "refresh_token": "vsrt_...",
  "scope": "identify email"
}

O access_token vale 7 dias. Guarde apenas no servidor. Se um mesmo code for apresentado duas vezes, o segundo uso falha e todos os tokens emitidos a partir dele são revogados.

Renovar o token#

Bash
curl -X POST https://api.vsync.lat/oauth2/token \
  -d grant_type=refresh_token \
  -d refresh_token=REFRESH_TOKEN \
  -d client_id=ID_DO_APP \
  -d client_secret=SECRET_DO_APP

A renovação faz rotação: você recebe um novo par de tokens e o antigo deixa de valer. Você pode pedir um scope menor, nunca maior que o original.

Chamar a API como a pessoa#

Envie Authorization: Bearer ACCESS_TOKEN. Esse token só funciona nos endpoints abaixo; ele não vale como sessão e não acessa nenhuma outra rota da API.

Bash
curl https://api.vsync.lat/oauth2/userinfo \
  -H "Authorization: Bearer ACCESS_TOKEN"
JavaScript
const user = await fetch("https://api.vsync.lat/oauth2/userinfo", {
  headers: { Authorization: `Bearer ${tokens.access_token}` },
}).then((r) => r.json());
// { id, username, displayName, avatarUrl, bannerUrl, createdAt, email?, verified? }

Use o id como identificador estável da pessoa; o nome de usuário pode mudar. email e verified só aparecem com o escopo email.

Referência dos endpoints#

Método e caminhoAutenticaçãoDescrição
GET /oauth2/authorize/infosessão da pessoaValida o pedido e devolve os dados da tela de consentimento
POST /oauth2/authorizesessão da pessoaEmite o código e devolve redirectUrl
POST /oauth2/tokenclienteauthorization_code e refresh_token
POST /oauth2/token/revokeclienteRevoga um access_token ou refresh_token (campo token)
GET /oauth2/@meBearerAplicativo, escopos, expiração e, com identify, o usuário
GET /oauth2/userinfoBearer com identifyDados públicos da conta
GET /oauth2/guildsBearer com guildsid, name, iconUrl, owner e permissions de cada servidor
GET /oauth2/authorizationssessão da pessoaApps que a pessoa autorizou
DELETE /oauth2/authorizations/:appIdsessão da pessoaRevoga todos os tokens daquele app

Para o dono do aplicativo: GET e PUT /developer/applications/:id/oauth2 (lista redirectUris) e POST /developer/applications/:id/oauth2/reset-secret.

Erros#

O endpoint de token responde no formato OAuth2, { "error": "...", "error_description": "..." }:

errorQuando
invalid_client (401)client_id desconhecido, client_secret errado, ou cliente sem secret e sem PKCE
invalid_grantCódigo usado, expirado ou de outro app; redirect_uri diferente; code_verifier errado; refresh token inválido
invalid_scopeEscopo desconhecido ou tentativa de ampliar escopos ao renovar
invalid_requestParâmetro obrigatório faltando
unsupported_grant_typeSó authorization_code e refresh_token

Os endpoints com Bearer respondem 401 para token inválido, expirado ou revogado, e 403 quando falta o escopo. Há limite de requisições por IP no endpoint de token; veja Erros e limites.

Controle da pessoa#

Em Configurações > Apps autorizados a pessoa vê quais apps têm acesso e pode revogar o acesso a qualquer momento. Revogar derruba todos os tokens e a renovação passa a falhar; trate isso como "sessão encerrada" no seu site.

Boas práticas#

  • Confira o state na volta e descarte se não bater.
  • Faça a troca do código e as chamadas à API no servidor; navegadores bloqueiam essas chamadas feitas direto de outros sites.
  • Use PKCE sempre que possível.
  • Não guarde o client_secret no repositório; use variáveis de ambiente.
  • Peça só os escopos de que precisa.