Entrar com Plicflix (fora do app)
O botão "Entrar com Plicflix" no seu site ou app. O jogador entra com a
conta do plicflix e o seu jogo recebe o mesmo jogador da entrada pelo app:
o mesmo id (pf_…, fixo por pessoa e por jogo) e o mesmo apelido. Assim, uma
conta do seu jogo serve às duas portas:
| porta | quando | como o jogo recebe o jogador |
|---|---|---|
| pelo app (SDK) | o jogador toca em Jogar no plicflix | token pft_… no endereço → POST /v1/ingresso/trocar |
| fora do app (esta página) | o jogador abriu o seu site direto, ou o seu app nativo | OAuth 2.0 + PKCE → POST /v1/oauth/token |
É OAuth 2.0 padrão (RFC 6749), com PKCE S256 obrigatório (RFC 7636). Qualquer
biblioteca de OAuth serve. O plicflix não emite id_token: o jogador vem
direto na resposta do token.
Para IAs: siga as seções 1 a 5 na ordem. A seção 4 é o caminho recomendado (com servidor). O exemplo inteiro, em Node, está na seção 4.3. Os ajudantes prontos ficam em
plicflix.mjseplicflix.go(servidor) eplicflix.js2.4+ (navegador).
1. Os endereços
| o quê | endereço |
|---|---|
| autorizar (o navegador vai até lá) | https://plicflix.com/oauth/authorize |
| trocar o código | POST https://api.plicflix.com/v1/oauth/token |
| quem é (com o access token) | GET https://api.plicflix.com/v1/oauth/userinfo |
| revogar o access token | POST https://api.plicflix.com/v1/oauth/revogar |
| descoberta (RFC 8414) | https://plicflix.com/.well-known/oauth-authorization-server |
client_id |
o slug do seu jogo |
client_secret (opcional) |
uma chave pk_… deste jogo (ou a antiga do estúdio) |
| escopo | perfil (openid e profile são aceitos como sinônimos) |
2. Cadastrar os endereços de volta
No portal: developers.plicflix.com → o seu jogo → Integração → Entrar com
Plicflix, um redirect_uri por linha (até 10). Ou pela API, com a chave:
curl -X PUT https://api.plicflix.com/v1/parceiro/jogos/SEU-SLUG/oauth \
-H "Authorization: Bearer pk_…" -H "Content-Type: application/json" \
-d '{"redirect_uris":["https://seujogo.com/api/plicflix/volta","http://localhost:5173/api/plicflix/volta"]}'
# → {"client_id":"SEU-SLUG","redirect_uris":[…],"authorization_endpoint":…,"token_endpoint":…}
As regras:
https://….http://só vale emlocalhost,127.0.0.1e::1(para testar).- App nativo: um esquema próprio com ponto no nome (
com.estudio.jogo:/oauth, RFC 8252). - Sem
#. A comparação é exata, caractere por caractere, inclusive a query. - Vale em qualquer situação do jogo: rascunho, revisão ou publicado. O login é do seu site, não do catálogo. O que se exige é o estúdio ativo (taxa de entrada paga, não suspenso). Sem isso, a página mostra o erro e não volta.
3. O fluxo
seu jogo navegador plicflix
│ 1. gera verifier + state │ │
│──── 302 /oauth/authorize ─────▶│──────────────────────────────▶ │ 2. entra (se precisar)
│ │ │ e autoriza (1ª vez)
│◀──── redirect_uri?code&state ──│◀────────────────────────────── │
│ 3. confere o state │
│──── POST /v1/oauth/token (code + verifier [+ pk_]) ───────────▶ │
│◀─── { jogador: { id: "pf_…", nome }, jogo, assinante, access_token } │
│ 4. acha/cria a conta por jogador.id e abre a SUA sessão │
1. Mandar o navegador para:
https://plicflix.com/oauth/authorize?response_type=code
&client_id=SEU-SLUG
&redirect_uri=https%3A%2F%2Fseujogo.com%2Fapi%2Fplicflix%2Fvolta
&state=ALEATORIO ← guarde (cookie curto); confira na volta
&code_challenge=BASE64URL(SHA256(verifier))
&code_challenge_method=S256
&scope=perfil
[&prompt=consent] ← pergunta de novo mesmo se já autorizou
O verifier tem de 43 a 128 caracteres de [A-Za-z0-9-._~] (por exemplo, 48
bytes aleatórios em base64url).
2. O plicflix cuida do resto:
- quem já está logado no plicflix nesse navegador não digita nada;
- quem não está entra, ou cria a conta e confirma o e-mail, ali mesmo;
- da segunda vez em diante a autorização é automática: o jogador nem vê a tela.
A tela mostra o que o jogo recebe (o apelido, um id só deste jogo e se é assinante) e o que nunca recebe (o e-mail, a senha, os amigos).
3. A volta. O navegador chega em redirect_uri?code=pfc_…&state=…. Se o
jogador cancelou, chega com error=access_denied&state=…. O código vale 5
minutos e uma troca.
Um pedido malformado volta com error=invalid_request, invalid_scope ou
unsupported_response_type. Se o client_id ou o redirect_uri não
conferem, o plicflix não volta: mostra o erro na própria página.
4. A troca, de preferência no seu servidor:
curl -X POST https://api.plicflix.com/v1/oauth/token \
-u "SEU-SLUG:pk_…" \
-d grant_type=authorization_code -d code=pfc_… \
-d redirect_uri=https://seujogo.com/api/plicflix/volta -d code_verifier=…
{
"jogador": { "id": "pf_3k2j…", "nome": "Ana", "avatar": "https://midia.plicflix.com/midia/avatares/aurea-lena.png" },
"jogo": "seu-slug",
"assinante": true,
"sub": "pf_3k2j…",
"name": "Ana",
"picture": "https://midia.plicflix.com/midia/avatares/aurea-lena.png",
"access_token": "pfa_…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "perfil"
}
- Quem entra é o perfil escolhido no plicflix daquele aparelho (cada
conta tem até 5).
jogador.avatar(epicture, no padrão OpenID) é a imagem dele: URLhttpspública, 256×256. Sem imagem,avatarvem""epicturenão vem. - O corpo pode ser
application/x-www-form-urlencoded(o padrão) ou JSON. - A chave vai como Basic (
client_id:pk_…), comoclient_secretno corpo ou comoAuthorization: Bearer pk_…. - Sem a chave, o pedido é de um cliente público (o jogo sem servidor, o app nativo): o PKCE é a prova.
jogador.idé igual ao da entrada pelo app (/v1/ingresso/trocar): ligue a conta por ele.
5. Depois: o access_token vale 1 hora e só serve para
GET /v1/oauth/userinfo, que devolve as mesmas chaves (sem o token). Não há
refresh token: o seu jogo abre a própria sessão. Para saber de novo quem
é, repita o fluxo; da segunda vez em diante ele é automático e invisível.
4. Com servidor (recomendado)
4.1 As duas rotas
GET /api/plicflix/oauth:- gere
verifierestate(novoPKCE()); - guarde os dois num cookie
HttpOnly; Secure; SameSite=Laxde 10 minutos; - responda
302paraurlDeEntrada(...).
- gere
GET /api/plicflix/volta:- confira
statecontra o cookie e apague o cookie; - se veio
error, mande o jogador de volta à sua tela de login; - chame
trocarCodigo(code, …)com a chavepk_; - ache ou crie a conta por
jogador.id, abra a sessão e responda302para o jogo.
- confira
A conta segue as mesmas regras da entrada pelo app (SDK): coluna
única plicflix_id, login interno reservado (pf_…@plicflix.invalid) e apelido
atualizado a cada entrada.
4.2 O botão
O botão oficial, como link para a sua rota:
<script src="/plicflix.js" defer></script>
<plicflix-entrar href="/api/plicflix/oauth" largura="100%"></plicflix-entrar>
Tem os estilos destaque, solido, simples e o seu próprio (proprio),
explicados com todas as opções e as regras da marca em BOTAO. O
código já preenchido com o seu jogo sai da página Botão oficial.
4.3 Exemplo completo (Node 18+, sem dependências)
import { createServer } from "node:http";
import { novoPKCE, urlDeEntrada, trocarCodigo } from "./plicflix.mjs"; // PLICFLIX_CHAVE no ambiente
const CLIENTE = "seu-slug";
const VOLTA = "https://seujogo.com/api/plicflix/volta";
const cookies = (req) => Object.fromEntries((req.headers.cookie || "").split(/; */).filter(Boolean).map((c) => c.split("=").map(decodeURIComponent)));
createServer(async (req, res) => {
const url = new URL(req.url, "https://seujogo.com");
if (url.pathname === "/api/plicflix/oauth") {
const { verificador, desafio, estado } = novoPKCE();
res.writeHead(302, {
"Set-Cookie": `pf_oauth=${estado}.${verificador}; Path=/api/plicflix; HttpOnly; Secure; SameSite=Lax; Max-Age=600`,
Location: urlDeEntrada({ cliente: CLIENTE, volta: VOLTA, desafio, estado }),
});
return res.end();
}
if (url.pathname === "/api/plicflix/volta") {
const [estado, verificador] = (cookies(req).pf_oauth || ".").split(".");
const apagar = "pf_oauth=; Path=/api/plicflix; Max-Age=0";
if (!estado || url.searchParams.get("state") !== estado || !url.searchParams.get("code")) {
res.writeHead(302, { "Set-Cookie": apagar, Location: "/sign-in?erro=plicflix" });
return res.end();
}
const r = await trocarCodigo(url.searchParams.get("code"), { cliente: CLIENTE, volta: VOLTA, verificador });
const conta = await acharOuCriarConta(r.jogador.id, r.jogador.nome); // a SUA conta
res.writeHead(302, { "Set-Cookie": [apagar, await abrirSessao(conta)], Location: "/play" });
return res.end();
}
}).listen(8080);
Em Go é o mesmo, com plicflix.NovoPKCE(), plicflix.URLDeEntrada(cliente, volta, pk) e cliente.TrocarCodigo(ctx, cliente, code, volta, verificador).
Os dois ajudantes estão em plicflix.go.
5. Sem servidor (jogo só de navegador)
O SDK faz tudo:
<script src="/plicflix.js"></script>
<div id="entrar"></div>
<script type="module">
const CLIENTE = "seu-slug", VOLTA = location.origin + "/";
const r = await Plicflix.voltouDoPlicflix(); // na volta: troca direto na API (cliente público)
if (r) iniciar(r.jogador); // { id: "pf_…", nome }
else Plicflix.botaoEntrar("#entrar", { cliente: CLIENTE, volta: VOLTA }); // = <plicflix-entrar cliente volta>
</script>
voltouDoPlicflix()confere ostate, troca o código e limpa a URL.- Com
{ servidor: "/sua/rota" }, ele manda{ code, code_verifier, redirect_uri }ao seu servidor em vez de trocar direto. É o meio-termo para quem já tem uma página e quer trocar no servidor. - Como tudo o que roda no navegador, o resultado de um cliente público serve para mostrar o nome e guardar o progresso local. Nunca use para proteger moedas, ranking ou compras: para isso, troque no servidor (seção 4).
6. Segurança (confira cada uma)
- O
stateé aleatório, fica num cookieHttpOnlye é conferido na volta. - O
verifiernunca sai do seu lado: só ocode_challengevai na URL. - A chave
pk_…só existe no servidor (nunca no navegador nem no app). - A conta é achada por
jogador.id, nunca pelo apelido (o apelido muda). - O login interno
…@plicflix.invalidé recusado no seu cadastro normal. - Os
redirect_uridelocalhostsaem da lista antes de publicar, se você não quiser que funcionem em produção.
7. Erros
O token responde no formato do OAuth: {"error": "...", "error_description": "..."}.
| status | error |
quando |
|---|---|---|
400 |
invalid_grant |
o código é inválido, venceu (5 min), já foi usado ou é de outro jogo; ou o redirect_uri é diferente; ou o code_verifier não confere. Um código que falha morre: recomece o fluxo. |
400 |
invalid_request |
falta code ou code_verifier, ou o corpo é inválido |
400 |
unsupported_grant_type |
só authorization_code |
401 |
invalid_client |
o client_id não existe ou a chave não é deste jogo (nem a antiga do estúdio dono) |
401 |
invalid_token |
userinfo: o pfa_ é inválido ou venceu |
429 |
— | limite por IP; espere um minuto |
Na volta para o seu redirect_uri, os erros possíveis são access_denied (o
jogador cancelou), invalid_request (faltou o PKCE S256), invalid_scope e
unsupported_response_type.
8. Testar
- Cadastre
http://localhost:PORTA/api/plicflix/volta(seção 2). - Use uma conta testadora do jogo (com o e-mail confirmado) se ele ainda não está publicado.
- Abra
http://localhost:PORTA/api/plicflix/oauthe entre: você volta logado no seu jogo. Ojogador.idé o mesmo de quando a mesma conta abre o jogo pelo app. - Abra de novo: desta vez a volta é direta, sem a tela de autorizar. Para ver
a tela outra vez, use
prompt=consent.
