‫Instrutor: Neste vídeo e nos próximos,
‫vamos implementar uma funcionalidade de
‫redefinição de senha amigável, que é uma espécie de
‫padrão na maioria dos aplicativos da web.
‫E provavelmente, você já usou a redefinição de
‫senha em algum site antes e,
‫normalmente, funciona assim.
‫Você só precisa fornecer seu
‫endereço de e-mail e receberá um e-mail
‫com um link onde pode clicar e que
‫o levará a uma página onde poderá inserir uma nova senha.
‫Este é um procedimento muito padrão e também
‫é assim que iremos implementá-lo
‫aqui neste aplicativo.
‫Basicamente, existem duas etapas.
‫A primeira é que o usuário envie uma solicitação de
‫postagem para uma rota de esquecimento de senha, apenas com este endereço de e-mail.
‫Isso criará um token de
‫redefinição e o enviará ao endereço de e-mail fornecido.
‫Apenas um token simples e aleatório, não um JSON Web Token.
‫Essa é uma diferença aqui.
‫Então, na segunda parte, que será o
‫próximo vídeo, o usuário então envia aquele token de
‫seu e-mail junto com uma nova senha para atualizar sua senha.
‫Basicamente, teremos exportações ponto esqueci a senha, que é o
‫primeiro passo.
‫Então solicite, responda e em seguida e depois como um segundo
‫passo, temos o reset de senha.
‫Então, vamos seguir em frente e implementar essas duas rotas.
‫Ok, e isso, é claro, em seu roteador de usuário ou
‫arquivo de rotas de usuário.
‫Vamos colocá-los também aqui e,
‫na verdade, posso apenas duplicar essas linhas aqui.
‫Por isso, novamente esquecemos a senha,
‫que só receberá o
‫endereço de e-mail e a seguir redefiniremos a senha, que
‫receberá o token assim como a nova senha.
‫Este é o
‫que vamos começar a implementar nesta palestra.
‫Vamos, como antes, especificar nossos passos aqui.
‫Portanto, primeiro obtenha o usuário com
‫base no e-mail postado e,
‫em seguida, gere o token aleatório.
‫E então, basicamente, envie-o de volta como um e-mail.
‫Essas coisas são muito comuns para nós neste momento.
‫Então, usuário, vamos aguardar o usuário dot find e agora ele encontra
‫um, não é encontrado pelo
‫id porque não sabemos o id do usuário.
‫E o usuário, é claro, também não sabe seu próprio
‫id, então especificamos o endereço de e-mail.
‫Basicamente, é o único dado conhecido.
‫E isso é stand on request dot body dot endereço de e-mail.
‫E, claro, agora precisamos dizer
‫que estamos em uma função assíncrona e, como antes, vamos envolvê-la
‫em catch async.
‫Salve e o erro desaparecerá.
‫Em seguida, na próxima etapa, vamos
‫verificar se o usuário existe.
‫Portanto, se não houver usuário, retorne ao próximo middleware, é
‫claro, com um novo erro.
‫Nenhum usuário tem esse endereço de e-mail.
‫E então podemos colocar um 404, que como você já
‫sabe, significa não encontrado.
‫Em seguida, vamos gerar o token aleatório e para
‫isso, mais uma vez,
‫vamos criar um método instantâneo no usuário.
‫Porque, mais uma vez, isso realmente tem a ver com
‫os próprios dados do usuário.
‫E vamos escrever um pouco de código,
‫então, se fosse apenas uma linha de código,
‫é claro que poderíamos simplesmente colocá-lo bem aqui.
‫Mas precisamos de algumas linhas
‫de código e, portanto, é um pouco
‫mais limpo separá-lo em sua própria função.
‫E isso geralmente com o Mongoose é melhor como um método instantâneo.
‫Então aqui embaixo, vamos editar aqui no final.
‫Portanto, os métodos de ponto do esquema do usuário ponto criam o token de redefinição de senha.
‫Um nome bastante longo e descritivo.
‫Gosto de fazer assim,
‫para saber exatamente com o que estou lidando.
‫O token de redefinição de senha deve ser basicamente uma string aleatória,
‫mas, ao mesmo tempo, não
‫precisa ser tão criptograficamente forte quanto o hash de senha
‫que criamos antes.
‫Podemos apenas usar a função de bytes aleatórios
‫muito simples do módulo criptográfico integrado.
‫Vamos prosseguir e realmente adicionar isso.
‫Crypto requer e, novamente, é um módulo de nó embutido, portanto, não
‫há necessidade de instalar nada.
‫Legal.
‫Agora, vamos gerar nosso token.
‫E para isso, usamos bytes aleatórios de crypto dot e
‫então aqui precisamos especificar o número de
‫caracteres basicamente.
‫E, no final, também
‫o convertemos em uma string hexadecimal.
‫Duas
‫strings e então podemos especificar a opção hex aqui.
‫Agora, se você
‫está se perguntando por que
‫estamos criando esse token, acho que ainda não expliquei.
‫Basicamente, esse token é o que enviaremos
‫ao usuário e, na verdade, é como uma redefinição de
‫senha que o usuário pode usar para criar uma nova senha real.
‫E, claro, apenas o usuário terá acesso a esse token.
‫E, de fato, ele realmente se comporta como uma senha.
‫Como é essencialmente uma senha, significa que
‫se um hacker conseguir acessar nosso banco de dados, isso
‫permitirá que o hacker obtenha acesso à
‫conta definindo uma nova senha.
‫Se simplesmente armazenássemos este token de redefinição
‫em nosso banco de dados agora, se algum invasor obtivesse acesso ao
‫banco de dados, ele poderia usar esse
‫token e criar uma nova senha usando esse token em
‫vez de você fazê-lo.
‫Eles controlariam efetivamente sua conta, em vez
‫de você fazer isso.
‫Assim como uma senha, nunca devemos armazenar
‫um token de redefinição simples no banco de dados.
‫Vamos criptografá-lo, mas como
‫antes com a senha, ele
‫não precisa de um método de criptografia
‫criptograficamente forte.
‫Porque esses tokens de redefinição são um vetor de
‫ataque muito menos perigoso.
‫Novamente, vamos apenas usar o módulo de
‫criptografia embutido.
‫Funciona dessa maneira estranha.
‫Dizemos crypto, em seguida, criamos o hash com
‫o algoritmo sha 256, então precisamos dizer update
‫e, em seguida,
‫a variável onde o token está armazenado.
‫Qualquer string que desejamos criptografar basicamente.
‫E então precisamos dizer digerir e, em seguida, armazená-lo novamente
‫como um hexadecimal.
‫E agora, onde vamos realmente salvar este token de reinicialização?
‫Bem, vamos criar um novo campo em nosso esquema de banco de dados.
‫Claro, queremos salvá-lo no banco de dados, para
‫que possamos compará-lo com
‫o token que o usuário fornece.
‫Vamos fazer isso aqui no final.
‫Token de redefinição de senha, essa
‫é a string.
‫E então também expira a redefinição de senha.
‫Porque esta reinicialização irá
‫realmente expirar após um determinado período de tempo como medida de segurança.
‫Você terá apenas 10 minutos para redefinir
‫sua senha.
‫Vamos agora usar isso.
‫Este token de redefinição de senha de ponto é então igual
‫a esta criptografia.
‫Em seguida, vamos definir expirações de redefinição de senha e
‫vamos definir isso para ponto de data agora e, em seguida,
‫simplesmente adicionar alguns segundos a isso.
‫Queremos que funcione por 10
‫minutos e, portanto, são 10 e depois precisamos dele em milissegundos.
‫Vezes 60 para segundos e depois 1000 para milissegundos.
‫E também quero devolver o token de texto simples
‫porque é realmente o que enviaremos
‫por e-mail.
‫Retorne o token de redefinição.
‫Precisamos enviar por e-mail o
‫token de redefinição não criptografado porque,
‫do contrário, não faria muito sentido criptografá-lo.
‫Se o token que
‫estava no banco de dados fosse exatamente o
‫mesmo que poderíamos usar para realmente
‫alterar a senha, então isso não seria nenhuma criptografia.
‫Enviamos um token por e-mail
‫e então temos a versão criptografada em nosso banco de dados.
‫E aquele criptografado é basicamente inútil para
‫alterar a senha.
‫É como quando
‫salvamos apenas a própria senha criptografada
‫no banco de dados, assim como fizemos
‫aqui, onde criptografamos a senha usando bcrypt.
‫Lembre-se de que você só salva dados confidenciais
‫em uma forma criptografada e depois compare-os
‫com a versão criptografada que está no banco
‫de dados.
‫Basta registrar esses dois no
‫console, o que tornará nossas vidas um pouco mais fáceis no futuro.
‫Digamos token de redefinição e estou efetuando login
‫aqui como
‫um objeto porque, dessa forma, ele realmente me dirá o
‫nome da variável junto com seu valor.
‫E então o mesmo com este token de redefinição de senha de ponto.
‫Este realmente não funciona com a
‫escrita de objetos, este novo jeito ES6 e
‫vamos deixar por isso mesmo.
‫De qualquer forma, vamos
‫voltar aqui e usar essa função.
‫Portanto, lembre-se de como retornamos o token de redefinição
‫e vamos armazená-lo aqui.
‫Portanto, o token de redefinição é igual ao conjunto de pontos do usuário e não
‫tenho mais certeza do nome.
‫Crie um token de redefinição de senha, de
‫modo que seja longo.
‫Tudo bem e está feito, mas
‫na verdade o que fizemos foi apenas modificar
‫os dados aqui.
‫Quando definimos esta senha de ponto expira, por exemplo,
‫para este valor, na verdade não
‫atualizamos o documento.
‫Nós não o salvamos.
‫Nós apenas o
‫modificamos, mas agora precisamos salvá-lo.
‫Digamos que o usuário aguarde o salvamento do ponto.
‫Mas observe o que acontece enquanto usamos isso agora.
‫Vamos apenas pegar este aqui.
‫Esta é a rota que encontramos antes.
‫E agora temos que essa rota ainda não está definida.
‫Vamos ver por que isso acontece.
‫Na rota do usuário, claramente temos o mesmo url aqui, mas
‫vejo que realmente precisamos fazer uma solicitação de postagem.
‫Certo, certo, mas agora recebemos um erro dizendo
‫forneça e-mail e senha.
‫E foi isso que eu quis dizer quando disse para
‫ver o que acontece quando você tenta fazer isso.
‫Isso acontece porque estamos tentando salvar um documento,
‫mas não especificamos todos os dados obrigatórios, portanto, os
‫campos que marcamos como obrigatórios.
‫Vamos consertar isso rapidamente.
‫Tudo o que precisamos fazer é realmente passar uma opção especial
‫para este método de salvamento do ponto do usuário.
‫Dizemos
‫validar antes de salvar
‫definido como falso.
‫Isso desativará todos os validadores que especificamos
‫em nosso esquema.
‫São essas pequenas coisas que você precisa saber
‫que farão toda a diferença.
‫Bem, eu também não sabia realmente que isso existia
‫porque ninguém realmente sabe todas as coisas.
‫É impossível.
‫Uma biblioteca como a Mongoose é simplesmente muito grande para
‫você saber tudo que existe.
‫Fui em frente e li a documentação do
‫Mongoose e foi aí que encontrei essa opção extremamente útil.
‫Tudo isso só para dizer que ninguém
‫sabe tudo e por
‫isso é realmente um bom hábito,
‫caso você
‫tenha problemas, dê uma olhada
‫na documentação da biblioteca que está usando.
‫Vamos dar uma olhada nisso agora.
‫E ainda obtemos o mesmo erro aqui, mas
‫vejo aqui que ele
‫realmente vem da função de login.
‫Vamos dar uma olhada no que está acontecendo aqui.
‫Vamos dar uma olhada nas rotas também.
‫Ah, ok, então aqui está o problema.
‫Agora estamos tentando chamar o
‫manipulador de login, o que, obviamente, não faz sentido.
‫Aqui está a senha esquecida.
‫Aqui está a senha de redefinição.
‫E o erro que obtivemos antes não foi devido
‫à validação.
‫Vamos enviar novamente e agora obtemos
‫o erro de que não há nenhum
‫usuário com este
‫endereço de e-mail e isso é porque não especificamos
‫nenhum endereço de e-mail no corpo.
‫Nós testamos isso
‫e agora é hora de realmente testá-lo
‫com um e-mail de usuário.
‫Tudo bem.
‫E agora não deve
‫fazer nada, porque não estamos enviando nenhuma resposta.
‫Vamos apenas cancelar
‫isso porque tudo que eu estava
‫realmente interessado é em ver esses tokens aqui e
‫também em dar uma olhada no objeto de usuário.
‫Este aqui é o token de redefinição original, então
‫você vê que é uma string hexadecimal aleatória
‫e então temos a criptografada aqui.
‫Este lembrete é aquele que não deveria estar no
‫banco de dados, terminando em a901.
‫Vamos dar uma olhada nisso.
‫E, de fato, aqui
‫está, token de redefinição de senha terminando neste a901.
‫E também a data, que na verdade é daqui a 10 minutos.
‫Agora você sabe a que horas estou gravando este vídeo.
‫Enfim, mas funcionou muito bem.
‫E esta é realmente a primeira
‫parte da criação da funcionalidade de redefinição de senha.
‫No próximo vídeo, enviaremos
‫este token aqui por e-mail para o usuário e, na
‫verdade, preparamos um vídeo separado apenas para
‫aprender como realmente enviar e-mail com node
‫para js.
‫É muito divertido,
‫então não espere para ir para lá imediatamente.