Roadmap
Avançado

Text-based MMORPG com JavaScript

Entenda o processo de criação de um jogo MMORPG web com JavaScript

react
nextjs
javascript
prisma
trpc
tailwind

Configurando a autenticação

Se você é dos mais atentos, deve ter notado que após rodar o projeto e abrir ele no seu navegador ele da a seguinte mensagem no seu console:

[next-auth][warn][NO_SECRET]
https://next-auth.js.org/warnings#no_secret
Clique aqui para expandir

Isso acontece porque o NextAuth precisa de um secret para funcionar, então vamos criar um secret para ele.

abra o arquivo .env na linha 12 altere o valor de NEXTAUTH_SECRET para qualquer coisa, pode ser uma string aleatoria, mas lembre-se de não compartilhar esse valor com ninguem.

NEXTAUTH_SECRET="STRINGALEATORIAQUENINGUEMDEVESABER"
Clique aqui para expandir

vai ficar assim:

Secret

Pronto agora vamos fazer o setup do nosso discord, assim podemos usar ele para autenticar os usuarios.

Configurando o Discord

Vamos ter que criar uma aplicação no discord para poder usar ele como provider de autenticação, então vamos la.

Entre no site: Developer Portal

Developer Portal

Caso o seu esteja em branco tudo bem, isso é porque eu ja criei outras aplicações antes, mas o processo vai ser o mesmo.

Clique em New Application no canto superior direito:

New Application

Coloque o nome da sua aplicação aceite os termos e clique em Create, essa tela deve aparecer para você em sequencia:

Application

Depois de criada a aplicação, vamos na aba OAuth2 e vamos copiar o client id e o client secret e vamos colar no nosso arquivo .env

OAUTH

Se o seu client secret não estiver aparecendo, clique em regenerate e ele vai aparecer.

Você não deve compartilhar o seu client secret com ninguem, se alguem tiver acesso a ele, pode fazer o que quiser com a sua aplicação.

Caso você não tenha configurado o 2FA no seu discord, ele vai pedir para você configurar, é bem simples, basta seguir os passos que ele pede.

Depois de copiado os dados do discord, vamos colar no nosso arquivo .env

.env

Não adianta tentar usar os dados que eu coloquei aqui, porque eu ja deletei a aplicação, então não vai funcionar.

Pronto agora vamos rodar o projeto novamente e ver o que acontece.

Clique em Sign In e depois em Sign in with Discord

Sign In

Como não configuramos a url de callback, ele vai dar um erro, mas não se preocupe, vamos resolver isso agora.

erro

Primeiro copie toda a URL do navegador, em seguida vamos nesse site: URL Decoder

Cole a URL copiada e clique em decode, vai aparecer uma URL parecida com essa:

URL

A informação que nos interessa é a que esta no meio da URL, precisamos da Redirect URI, então vamos copiar.

Redirect URI

No nosso caso a Redirect URI é: http://localhost:3000/api/auth/callback/discord

Vamos voltar no site do discord e vamos na aba OAuth2 e vamos colar a Redirect URI no campo Redirects.

Adicione o link e clique em save changes.

Redirect URI

Agora vamos tentar fazer login novamente:

Vai aparecer uma tela como essa, basta clicar em autorizar:

Autorizar

O erro que vai aparecer agora é o: Try signing in with a different account.

No nosso terminal o seguinte erro vai aparecer:

prisma:query SELECT `main`.`Account`.`id`, `main`.`Account`.`userId` FROM `main`.`Account` WHERE ((`main`.`Account`.`provider` = ? AND `main`.`Account`.`providerAccountId` = ?) AND 1=1) LIMIT ? OFFSET ?
prisma:error
Invalid `p.account.findUnique()` invocation in
mmorpg-nextjs\node_modules\@next-auth\prisma-adapter\dist\index.js:211:45

  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),
  209 async getUserByAccount(provider_providerAccountId) {
  210     var _a;
 211     const account = await p.account.findUnique(
The table `main.Account` does not exist in the current database.
[next-auth][error][adapter_error_getUserByAccount]
https://next-auth.js.org/errors#adapter_error_getuserbyaccount
Invalid `p.account.findUnique()` invocation in
mmorpg-nextjs\node_modules\@next-auth\prisma-adapter\dist\index.js:211:45

  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),
  209 async getUserByAccount(provider_providerAccountId) {
  210     var _a;
 211     const account = await p.account.findUnique(
The table `main.Account` does not exist in the current database. {
  message: '\n' +
    'Invalid `p.account.findUnique()` invocation in\n' +
    'mmorpg-nextjs\\node_modules\\@next-auth\\prisma-adapter\\dist\\index.js:211:45\n' +
    '\n' +
    '  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),\n' +
    '  209 async getUserByAccount(provider_providerAccountId) {\n' +
    '  210     var _a;\n' +
    '→ 211     const account = await p.account.findUnique(\n' +
    'The table `main.Account` does not exist in the current database.',
  stack: 'PrismaClientKnownRequestError: \n' +
    'Invalid `p.account.findUnique()` invocation in\n' +
    'mmorpg-nextjs\\node_modules\\@next-auth\\prisma-adapter\\dist\\index.js:211:45\n' +
    '\n' +
    '  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),\n' +
    '  209 async getUserByAccount(provider_providerAccountId) {\n' +
    '  210     var _a;\n' +
    '→ 211     const account = await p.account.findUnique(\n' +
    'The table `main.Account` does not exist in the current database.\n' +
    '    at si.handleRequestError (mmorpg-nextjs\\node_modules\\@prisma\\client\\runtime\\library.js:125:6817)\n' +
    '    at si.handleAndLogRequestError (mmorpg-nextjs\\node_modules\\@prisma\\client\\runtime\\library.js:125:6151)\n' +
    '    at si.request (mmorpg-nextjs\\node_modules\\@prisma\\client\\runtime\\library.js:125:5859)\n' +
    '    at async l (mmorpg-nextjs\\node_modules\\@prisma\\client\\runtime\\library.js:130:9805)\n' +
    '    at async getUserByAccount (mmorpg-nextjs\\node_modules\\@next-auth\\prisma-adapter\\dist\\index.js:211:29)',  name: 'PrismaClientKnownRequestError'
}
[next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
https://next-auth.js.org/errors#oauth_callback_handler_error
Invalid `p.account.findUnique()` invocation in
mmorpg-nextjs\node_modules\@next-auth\prisma-adapter\dist\index.js:211:45

  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),
  209 async getUserByAccount(provider_providerAccountId) {
  210     var _a;
 211     const account = await p.account.findUnique(
The table `main.Account` does not exist in the current database. PrismaClientKnownRequestError:
Invalid `p.account.findUnique()` invocation in
mmorpg-nextjs\node_modules\@next-auth\prisma-adapter\dist\index.js:211:45

  208 getUserByEmail: (email) => p.user.findUnique({ where: { email } }),
  209 async getUserByAccount(provider_providerAccountId) {
  210     var _a;
 211     const account = await p.account.findUnique(
The table `main.Account` does not exist in the current database.
    at si.handleRequestError (mmorpg-nextjs\node_modules\@prisma\client\runtime\library.js:125:6817)
    at si.handleAndLogRequestError (mmorpg-nextjs\node_modules\@prisma\client\runtime\library.js:125:6151)
    at si.request (mmorpg-nextjs\node_modules\@prisma\client\runtime\library.js:125:5859)
    at async l (mmorpg-nextjs\node_modules\@prisma\client\runtime\library.js:130:9805)
    at async getUserByAccount (mmorpg-nextjs\node_modules\@next-auth\prisma-adapter\dist\index.js:211:29) {
  name: 'GetUserByAccountError',
  code: 'P2021'
Clique aqui para expandir

Isso acontece porque não criamos nossa base de dados ainda, então vamos fazer isso agora.

Criando a base de dados

Pare a execução do projeto e rode o seguinte comando:

npm run db:push
Clique aqui para expandir

> mmorpg-text-menthor@0.1.0 db:push
> prisma db push

Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Datasource "db": SQLite database "db.sqlite" at "file:./db.sqlite"

Your database is now in sync with your Prisma schema. Done in 64ms

 Generated Prisma Client (v5.8.1) to .\node_modules\@prisma\client in 93ms
Clique aqui para expandir

Pronto agora o nosso login deve funcionar, para os curiosos estamos usando o SQLite como banco e o arquivo fica na pasta prisma/db.sqlite

Vamos rodar o projeto de novo e fazer login.

Logado

Depois de logado você vai vai ver que estamos logado como nosso usuario do discord e agora temos acesso as rotas protegidas que vão servir para acessar as informações do jogo.

Caso tenha curiosidade, você pode abrir o arquivo db.sqlite com o DB Browser for SQLite e ver as informações que estão salvas no banco, ou rodar o comando do proprio prisma para rodar o prisma studio e ver essas informações.

npm run db:studio
Clique aqui para expandir
Opa, calma aí!

Parece que você não está logado, caso tenha interesse em salvar seu progresso de estudo faça login agora.