O curso Express. js - Módulo 9: autenticação e autorização | Shivendra Raghuvanshi | Skillshare
Pesquisar

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

O curso Express. js - Módulo 9: autenticação e autorização

teacher avatar Shivendra Raghuvanshi, Lead Developer and Online Teacher

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Introdução do curso

      2:38

    • 2.

      Autenticação e autorização - Uma introdução

      4:41

    • 3.

      Criando o modelo do usuário

      4:04

    • 4.

      Registrando usuários

      8:33

    • 5.

      Usando o Lodash

      6:03

    • 6.

      Hashing de senhas

      8:23

    • 7.

      Autenticando usuários

      5:20

    • 8.

      Testando a autenticação

      2:48

    • 9.

      Tokens da Web JSON

      5:58

    • 10.

      Gerando tokens de autenticação

      4:36

    • 11.

      Armazenando segredos em variáveis de ambiente

      7:25

    • 12.

      Definindo cabeçalhos de resposta

      4:30

    • 13.

      Encapsulando a lógica em modelos Mongoose

      8:17

    • 14.

      Middleware de autorização

      8:44

    • 15.

      Protegendo rotas

      3:50

    • 16.

      Obtendo o usuário atual

      4:50

    • 17.

      Desconectando usuários

      2:30

    • 18.

      Autorização baseada em funções

      6:59

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

1

Estudante

--

Projeto

Sobre este curso

Módulo 9: autenticação e autorização foca nos conceitos essenciais de autenticação e autorização em aplicativos web modernos. Você vai aprender como implementar medidas de segurança robustas para proteger suas APIs e gerenciar funções de usuário de forma eficaz. Do registro de usuários à geração e verificação de JSON Web Tokens (JWT), este módulo equipa você com tudo o que você precisa para proteger suas aplicações de backend.

O que você aprenderá

  • Crie um modelo de usuário com recursos de autenticação.
  • Implementar o registro seguro de usuários com senhas com hash.
  • Autenticar usuários com autenticação baseada em JWT.
  • Proteger rotas sensíveis com autorização e middleware baseados em funções.
  • Utilizar variáveis de ambiente para armazenamento seguro de segredos.
  • Gerenciar sessões de usuários, logouts e níveis de acesso para diferentes funções.

Conheça seu professor

Teacher Profile Image

Shivendra Raghuvanshi

Lead Developer and Online Teacher

Professor
Level: Intermediate

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Introdução do curso: Bem-vindo de volta ao curso Express Jazz, Modelo nove, autenticação e autorização. Meu nome é ShenRagunhi e serei seu instrutor Ao longo dos anos, tive o privilégio de criar sistemas de back-end seguros e escaláveis para uma variedade de aplicativos e estou aqui para compartilhar minha experiência Um dos meus melhores projetos envolveu a criação um sistema de autenticação de usuário para uma plataforma de comércio eletrônico, o que melhorou significativamente sua segurança e usabilidade Hoje, você aprenderá a construir algo igualmente impactante Neste módulo, vamos nos aprofundar na autenticação e autorização, dois aspectos críticos do desenvolvimento web moderno. Assim, você aprenderá como registrar usuários com segurança usando senhas com hash, autenticar usuários com os webtkens da JCN, proteger rotas confidenciais com middleware e, finalmente, implementar a autorização baseada em funções para gerenciar as permissões finalmente usuários com segurança usando senhas com hash, autenticar usuários com os webtkens da JCN, proteger rotas confidenciais com middleware e, finalmente, implementar a autorização baseada em funções para gerenciar as permissões do usuário. Esse conhecimento é crucial para proteger qualquer aplicativo de back-end e, ao final deste módulo, você estará confiante na implementação desses recursos em seus projetos Portanto, este módulo foi projetado para Bg em desenvolvedores que desejam levar seus aplicativos Express JS para o próximo nível. Se você concluiu os módulos anteriores, está tudo pronto para começar. conhecimento básico de JavaScript, recomendado o conhecimento básico de JavaScript, sem JS e Monger DB Autenticação e autorização são os pilares de qualquer aplicativo web seguro Ao dominar esses conceitos, você não apenas criará aplicativos mais seguros, mas também aumentará seu valor como desenvolvedor Essas são habilidades essenciais para criar plataformas centradas no usuário no mundo tecnológico atual E, finalmente, para o projeto, você integrará tudo o que aprendeu no aplicativo Fair Wheels. Então, mais especificamente, você implementará funcionalidade de registro e login de usuários, autenticando usuários com segurança usando tokens da web JCN Aplique autorização baseada em funções para proteger rotas e recursos. Ao final, você terá um sistema de gerenciamento de usuários seguro e escalável para o aplicativo Fair Wheels Este módulo é um divisor de águas para sua jornada de desenvolvimento do Bend Então, vamos criar aplicativos seguros juntos. vejo na primeira palestra. Vamos começar. 2. Autenticação e autorização - Uma introdução: Tudo bem, então, de volta ao nosso aplicativo Fair Wheels. Até agora, criamos esses endpoints de API. Assim, podemos gerenciar empresas, carros, clientes e aluguéis. Agora, quase todos os aplicativos existentes exigem algum tipo de autenticação e autorização. Então, nesta seção, vamos levar esse aplicativo para o próximo nível e implementar autenticação e autorização. Portanto, antes de prosseguirmos, quero ter certeza de que estamos na mesma página. Portanto, a autenticação é o processo de identificar se o usuário é quem afirma ser. É quando fazemos o login. Então, enviamos nosso usuário e senha para o servidor, e o servidor nos autentica A autorização é determinar se o usuário tem a permissão correta para realizar a operação em questão. Portanto, em nosso aplicativo Fair Wheels, queremos garantir que somente usuários autenticados ou somente usuários logados possam realizar operações que modifiquem dados Portanto, se o usuário for anônimo, se não estiver conectado, ele só poderá ler os dados desses endpoints Se eles quiserem criar uma nova empresa ou atualizar um carro, eles precisam ser autenticados primeiro Agora, como segurança adicional, queremos garantir que somente usuários administradores possam excluir dados. Então, esse é um segundo nível de autorização. Estamos falando sobre permissões aqui. Então, esses são os requisitos que vamos implementar nesta seção. Então, para fazer isso, precisamos adicionar dois novos endpoints ao nosso aplicativo Primeiro, devemos ser capazes de registrar usuários. Para isso, enviaremos uma solicitação de postagem para slash API slash USERS porque publicamos, criamos novos recursos Nesse caso, um novo usuário. Também devemos ser capazes de fazer login com um usuário, e isso é usado para autenticação. Agora, aqui está uma pergunta para você. Qual método SDDP devemos usar para implementar o login? Porque com o login, não estamos criando um novo recurso. Não estamos atualizando ou removendo um existente. Então, como podemos implementar isso em termos tranquilos? Esse é um daqueles cenários que você pode encontrar com frequência em aplicativos do mundo real. Às vezes, a operação com a qual você está lidando não tem essa semântica de criação, leitura, atualização e exclusão A forma como modelamos isso em termos repousantes é referindo a isso como solicitação ou comando Então você está criando uma nova solicitação de login ou um comando de login. Nesse caso, usaremos post porque estamos criando um novo recurso, então slash API slash Logins Agora, em seu aplicativo, talvez você queira armazenar todos os logins no aplicativo em uma coleção separada no Mongo Então, você pode ver que usar a postagem faz todo o sentido aqui. Mas mesmo que você não armazene logins individuais e queira apenas validar o usuário e a senha, você ainda pode tratar esse recurso como recurso login e usar post para criá-lo Agora, aqui está um exercício para você. Quero que você implemente essa API para registrar novos usuários. Então, para cada usuário, queremos ter essas propriedades, nome, e-mail e senha. Além disso, ao definir seu esquema para a propriedade de e-mail no objeto do tipo de esquema, defina a propriedade exclusiva Então, quando definimos o esquema, definimos o tipo de e-mail para um objeto que é nosso objeto de tipo de esquema Definimos o tipo aqui como string e também definimos exclusivo como verdadeiro. Então, com isso, garantimos que não armazenaremos dois documentos com o mesmo e-mail no Mongo Di B. Ok. Então, vá em frente e implemente somente essa API para registrar novos usuários. Eu vou fazer o mesmo na próxima palestra. 3. Criando o modelo do usuário: Tudo bem. Então, primeiro, vou definir um novo modelo de usuário. Então, aqui na pasta de modelos em um novo arquivo user dot js. Agora, para economizar tempo, vou até a empresa dot js e pego emprestado um código daqui Então copie de volta para userdtjs, cole aqui. Agora, no topo, temos esse esquema. Vou definir isso ao chamar o método do modelo. Realmente não há necessidade, neste caso, de definir isso como uma constante separada. Então, vamos pegar esse objeto de esquema e adicioná-lo aqui. E agora podemos nos livrar desse esquema. Ok, isso é melhor. Então esse é o nosso modelo. Devemos chamar esse usuário constante. E a coleção correspondente também deve ser de usuários. Agora, aqui, temos a propriedade name, que é uma string. É obrigatório e tem de 5 a 50 caracteres. Isso soa bem para mim. Em seguida, vamos adicionar e-mail. Então, vou pegar tudo isso de bom e duplicá-lo. E a segunda propriedade é o e-mail. Então, novamente, temos essas propriedades. Eu gostaria de aumentar o tamanho máximo para 255 caracteres Além disso, como eu disse na última palestra, devemos adicionar a propriedade exclusiva para garantir que não armazenemos dois usuários com o mesmo e-mail no Manga Divi E a última propriedade é Passwb. Então, vou copiar tudo isso, duplicar e adicionar essa propriedade de senha Agora vou definir o tamanho máximo das senhas para um valor maior porque vamos fazer o hash dessas senhas E aqui não precisamos da propriedade exclusiva. A seguir, nossa função de validação. Portanto, precisamos renomear isso para validar o usuário. Valide o usuário que usa um parâmetro do usuário. Aqui temos um nome de 5 a 50 caracteres e é obrigatório Temos um e-mail, que deve ter de 5 a 255 caracteres. Deveria ser obrigatório. E aqui também chamamos o método de e-mail para garantir que seja um e-mail válido. E, finalmente, temos a senha, que também é uma string com mínimo cinco caracteres e no máximo, digamos, 255, conforme necessário Então essa é a senha que o usuário envia em texto simples. Vamos fazer um hash disso, que será uma sequência mais longa, e essa é a sequência que armazenaremos na Mongo TV Então, terminamos com nossa função de usuário válida. Agora precisamos exportar nosso modelo de usuário, então não precisamos da primeira instrução de exportação que é para nossa exclusão de esquema Aqui vamos exportar isso como usuário, e nossa função de validação também é boa Linda. Então, terminamos com nosso modelo de usuário. Na próxima palestra, adicionarei uma rota para registrar novos usuários 4. Registrando usuários: Tudo bem Agora vamos criar uma nova rota para registrar novos usuários. Então, aqui na pasta routes, vou adicionar um novo arquivo users dot js. Agora, mais uma vez, para economizar tempo, vou até as empresas dot js e copiarei essas declarações obrigatórias, bem como a segunda rota, em nosso novo módulo. Então copie, cole aqui. Novamente, copie a rota da postagem. E cole aqui. E, a propósito, só estou fazendo isso porque não quero perder seu tempo me vendo digitar tudo isso à mão. No mundo real, você deve evitar abordagem de copiar e colar, a menos que seja muito cuidadoso e leia cada linha do código copiado para ter certeza de que não cometeu um erro É sempre melhor digitar o código manualmente. Agora, vamos fazer mudanças. Então, no topo, precisamos importar o modelo do usuário em vez da empresa. Então, do usuário de modelos, importamos a classe de usuário, bem como a função de validação Também precisamos do Express e do Router. Então, aqui está nossa nova rota que é proposta para criar novos usuários. E, finalmente, precisamos exportar esse roteador. Então, module dot Exports. Nós configuramos isso para este roteador. Agora, precisamos voltar ao nosso ponto de índice JS e dizer ao Express que, para qualquer rota que comece com a barra ABS SRS, devemos usar esse roteador que estamos exportando aqui Então, vamos para Index ou Js. Na parte superior, vamos importar esse novo módulo. Então, usuários constantes. Definimos isso para exigir dos usuários da pasta de rotas. E então aqui chamamos o aplicativo que dá ao nosso caminho barra de usuários de APAs e nosso roteador, ou seja, usuários Ok, então nós construímos o quadro geral. Agora, vamos voltar ao nosso módulo de usuários e implementar essa nova rota. Então, aqui vamos validar a solicitação. Se não for válido, retornaremos um erro 400, que é uma solicitação incorreta. Caso contrário, criaremos um novo objeto de usuário e o salvaremos no banco de dados. Então, vamos manter as duas primeiras linhas exatamente como estão. Queremos validar a solicitação. Estamos usando nossa função de validação Joy. Portanto, se as propriedades de nome, e-mail ou senha não forem válidas, retornaremos um erro 400 ao cliente. Agora, em seguida, precisamos fazer outro tipo de validação. Você quer ter certeza de que esse usuário ainda não está registrado. Então, chamamos o usuário dot Fine one, passamos um objeto de consulta aqui. Estamos procurando um usuário com um determinado e-mail que é request dot body dot email. Então, observe que aqui, eu não usei fine by ID porque não estamos procurando o usuário pelo ID. Estamos procurando por uma de suas propriedades. Tão bom. Agora, isso retorna uma promessa. Então, aguardamos e obtemos um objeto de usuário. Agora, nesse caso, estou definindo uma variável em vez de uma constante porque vamos redefinir isso, como você verá em um segundo. Portanto, nesse caso, se tivermos esse objeto de usuário no banco de dados, devemos retornar um erro de solicitação incorreta ao cliente. Então, retorne a resposta dot status 400, que é uma solicitação inválida dot SEND e aqui está a mensagem que o usuário já registrou. Então, neste momento, temos um objeto de usuário válido. Esse usuário não está registrado no banco de dados, então precisamos salvá-lo no banco de dados. Então, aqui, vou redefinir esse objeto de usuário porque, neste momento, ele deveria ser não. Definimos isso para um novo usuário e aqui definimos as propriedades. Então, nome, definimos isso para solicitar corpo do ponto, nome do ponto. E-mail para solicitar e-mail dot body dot. E senha para solicitar a senha do corpo do ponto. Então esse é o nosso objeto de usuário. Agora vamos salvá-lo. Então aguarde, o usuário salve e, finalmente, devolva isso ao cliente Portanto, não precisamos dessas duas linhas para trabalhar com a empresa. Excluir. E, finalmente, devolva esse novo usuário ao cliente. Agora, vamos testar isso. Então, de volta ao Postman, vou enviar uma solicitação de postagem para 3.000 usuários slash APAS da porta Local Host E então, no corpo da solicitação, vou definir isso como Raw e definir o tipo como JSON Aqui passamos como objeto JSON com três propriedades, nome, Shiv, depois configuramos e-mail Vou definir um e-mail inválido e também não vou definir a senha Quero ter certeza de que nossa função de validação está funcionando corretamente. Então mande. Ok, recebemos um pedido ruim. Isso é bom. O tamanho do nome deve ter pelo menos cinco caracteres. Então, deixe-me mudar isso para Hewnder Alright. Agora vamos enviar outra solicitação. Recebemos outro pedido incorreto. O tamanho do e-mail deve ter pelo menos cinco caracteres. Então, vamos mudar isso para 12, três, quatro, cinco, seis, mas esse não é um e-mail válido. Então, agora devemos receber um erro diferente. O e-mail deve ser válido. Linda. Então, vamos mudar isso para testar 123 em regmil.com Vamos enviar outra solicitação. Ok, agora temos a senha necessária. Linda. Por fim, vamos adicionar uma senha com pelo menos cinco caracteres. Então, um, dois, três, quatro, cinco, envie. Desta vez, obtivemos uma resposta de 200. Linda. E esse é o objeto do usuário que você armazenou no banco de dados. Então você tem a propriedade ID, bem como nome, e-mail e senha. Agora, ao registrar um novo usuário, não queremos devolver sua senha ao cliente Então, isso é algo que vamos corrigir na próxima palestra. Mas vamos enviar outra solicitação com exatamente os mesmos valores. Desta vez, devemos receber um erro diferente, informando que o usuário já está registrado. Então mande. Ok, recebemos outro pedido incorreto, e aqui está a mensagem. Usuário já cadastrado. Linda. Então, na próxima aula, vamos modificar a resposta dessa API e do ponto 5. Usando o Lodash: Então, de volta ao nosso método post, queremos modificar a resposta para o cliente. Portanto, há duas opções aqui. Uma abordagem é retornar um objeto personalizado como esse, definindo o nome como nome do ponto do usuário e o e-mail como e-mail ponto do usuário. Dessa forma, podemos excluir a senha e as propriedades da versão. Essa abordagem é perfeita, mas nesta palestra, apresentarei uma biblioteca útil que oferece muitas funções utilitárias para trabalhar com objetos Se você é um desenvolvedor experiente em JavaScript, provavelmente sabe do que estou falando. Isso é Lourdes Então acesse lodash.com. Isso é lodash, que é basicamente a versão otimizada do sublinhado O underscore já existe há muito tempo. Ele tem muitos mecanismos utilitários para trabalhar com objetos, sequências de caracteres, matrizes e assim por diante Portanto, se você consultar a documentação, aqui podemos ver todas as funções utilitárias que temos para trabalhar com vários tipos. Temos muitas funções utilitárias para trabalhar com matrizes, números, cadeias de caracteres, objetos e assim por diante Portanto, o lodash é extremamente poderoso. E nesta palestra, mostrarei como usá-lo em seu aplicativo node Então, de volta ao terminal, o NPM instala o lodash. Portanto, observe que na versão atual estou usando 4.17 0.21. Tudo bem, agora, de volta ao código. Então, aqui no modelo do nosso usuário na parte superior, vou importar o Lodash Então, exija o Lodash. Agora, por convenção, armazenamos o resultado em uma constante chamada sublinhado Você pode chamar isso de qualquer coisa, você pode chamar isso de Lodash, mas por convenção, usamos sublinhado porque é curto Agora, esse objeto de sublinhado que temos aqui tem um método utilitário chamado pick so underscore dot Nós damos a isso um objeto. Nesse caso, nosso objeto de usuário e, em seguida, passe uma matriz de propriedades nesse objeto de usuário que queremos escolher. E isso retornará um novo objeto com apenas essas propriedades. Então, aqui nesta matriz, vou passar nome e e-mail. Então, quando chamarmos esse método de seleção, obteremos um novo objeto com essas duas propriedades, nome e e-mail. Agora, em vez de repetir manualmente o ponto do usuário, podemos usar esse método Pi Isso é mais elegante. Então, podemos substituir esse objeto aqui pelo que obtemos do método PI. simples quanto isso. Agora, talvez aqui, você também queira incluir a propriedade IR. Então é assim que usamos o método PIC. Da mesma forma, podemos modificar esse código e, em vez de repetir a solicitação ponto no corpo do ponto, solicitar ponto no corpo do ponto, solicitar ponto no corpo do ponto com sublinhado no ponto Então, vou substituir esse objeto underscore dot pig Pedimos que pague. Agora, aqui, podemos ter 50 propriedades. Um usuário mal-intencionado pode nos enviar propriedades para serem armazenadas no banco de dados. Só queremos escolher alguns deles a dedo. Então, passamos uma matriz. Estamos interessados apenas em nome, e-mail e senha. Ok, então criamos o usuário e o salvamos e, em seguida, retornamos esse objeto personalizado ao cliente. Vamos testar isso mais uma vez para garantir que tudo esteja funcionando. Então, terminal de back-end. Vamos executar o aplicativo. Linda. Agora, de volta ao Postman Vou enviar uma nova solicitação pelo servidor. Enviar. Ok, aqui está nosso novo objeto de usuário. Só temos ID, nome e e-mail. Agora, em todas essas solicitações até agora, enviei senhas muito simples. Se você quiser impor a complexidade da senha, existe um pacote NPM baseado no Joy chamado Joi password Complexity Joy chamado Joi Então, de volta ao Google, pesquise Joy password Complexity. Esse é o pacote NPM. Então, com isso, você pode configurar um objeto que determina a complexidade da senha em seu aplicativo. Número mínimo de caracteres, máximo, quantas letras minúsculas ou maiúsculas você deseja ter, quantos números e assim por diante. Portanto, o nome do pacote é Joy password complexity. Neste curso, não vamos usar isso porque é algo que você pode fazer sozinho. Tudo bem, nosso novo endpoint de API está em boas condições, mas estamos armazenando nossas senhas como texto simples, e isso é muito, muito ruim Então, na próxima palestra, mostrarei como fazer o hash dessas senhas 6. Hashing de senhas: Nesta palestra, mostrarei como fazer hash de senhas Para isso, vamos usar uma biblioteca muito popular chamada B crypt. Então, aqui no terminal, vamos instalar o B crypt. Instalar. Observe a versão que estou usando. Essa é a versão 5.1 0.1. Agora, aqui, vou criar um arquivo de playground, para que você aprenda a trabalhar com essa biblioteca BCRP e, em seguida, vamos pegar esse código e colocá-lo em uma rota para codificar a senha de Então, vamos criar um novo arquivo, hash dot js. Neste arquivo, primeiro, precisamos carregar o BCRP Isso retém um objeto. Nós o armazenamos aqui. Cripta B. Agora, para ter uma senha, precisamos de um sal. O que é sal? Bem, imagine que nossa senha seja um, dois, três, quatro. Quando fizermos o hash, vamos imaginar que obteremos uma string como essa Agora, esse algoritmo de hashing é uma maneira. Então, se temos A, B, CD, não podemos decifrar isso e obter um, dois, três, quatro Então, do ponto de vista da segurança, isso é ótimo. Se um hacker examinar nosso banco de dados, ele ou ela não conseguirá decifrar essas senhas criptografadas No entanto, eles podem compilar uma lista de senhas populares e criptografá-las. E então eles podem consultar o banco de dados do nosso aplicativo. Eles encontram essa senha hash e sabem que ABCD representa um, dois, três, quatro É por isso que precisamos de um SALT. Pois SALT é basicamente uma string aleatória que é adicionada antes ou depois dessa senha. Portanto, a senha com hash resultante será diferente. Cada vez com base na agressão usada. Ok, deixe-me mostrar isso em ação. Então, aqui chamamos B crypt dot Gen SLT. Observe que esse método tem duas versões. O primeiro é assíncrono. O segundo é síncrono. Como prática recomendada, você deve sempre usar métodos assíncronos porque, como eu disse no início do curso, em aplicativos de nós, temos um Não queremos manter esse tópico ocupado porque não podemos atender outros clientes. Então, chamamos GenSLT como argumento. Nós passamos o número de franzidas. Queremos executar esse algoritmo para gerar o SLT. Quanto maior o número, mais tempo será necessário para gerar o sal. Além disso, o SOT será mais complexo e difícil de quebrar Portanto, o valor padrão é dez. Vamos usar isso agora porque esse é um método assíncrono Podemos repassar o retorno de chamada aqui, e é isso que você vê na documentação oficial deles, bem como em muitos tutoriais na web. Mas esse método também tem uma sobrecarga que retorna uma promessa Então, em vez de enviar um retorno de chamada, recebemos uma promessa, aguardamos e depois recebemos o sal Então, agora precisamos envolver isso em uma função de atuação como run Ok, então vamos colocar esse sal no console. E, finalmente, vamos chamar essa função de execução. Agora, de volta ao nó terminal tem dois Js. Então esse é um exemplo de sal. Você pode ver o número de rodadas que usamos incluídas no sal Então, se usarmos 20 aqui em vez de dez, teríamos 20. Então, aqui temos uma longa sequência aleatória que é incluída como parte do hash de nossas senhas E com isso, toda vez que criptografamos nossa senha com um novo Salt, obtemos resultados diferentes Então, agora que temos um Salt, podemos usá-lo para codificar nossa senha Temos outro método aqui neste objeto da cripta B que é o hash Então, fornecemos nossos dados. Vamos imaginar que nossa senha seja um, dois, três, quatro, e dê o sal a ela. E, novamente, veja, o terceiro argumento pode ser um retorno de chamada. Não vamos usar isso. Em vez disso, receberemos a promessa que é retornada desse método. Então, aguardamos essa promessa e recebemos a senha criptografada. Então, agora vamos registrar isso no console também. Hashado. Ok, de volta ao nó terminal, hashed ou chase Ok, olha, na primeira linha, temos nosso sal. Na segunda linha, você também pode ver o sal aqui. Portanto, o SALT é incluído na senha com hash. A razão pela qual isso está incluído é porque, posteriormente, quando quisermos autenticar o usuário, queremos validar seu nome de usuário e senha Então, o usuário envia uma senha em texto simples. Precisamos fazer o hash novamente, mas precisamos ter o sal original usado para gerar esse hash Portanto, ao comparar a senha de texto simples com a senha com hash, B crypt precisa saber o sal original usado para fazer o hash Agora que você sabe como o B Crypt funciona, vamos pegar essas duas linhas e colocá-las em nosso manipulador de rotas Então corte-os daqui. Vamos até os usuários dot js. Ok, aqui está nosso objeto de usuário. Vamos colar essas linhas aqui. Então, geramos um sal e, em seguida, precisamos ter a senha. Em vez de um, dois, três, quatro, vamos usar a senha de ponto do usuário. Essa é uma senha em texto simples. Então, misturamos com sal e depois reiniciamos. Então, senha do ponto do usuário. Agora, no topo, também precisamos importar a cripta B, portanto, a cripta B constante Definimos isso para exigir o Bcrypt. Agora, aqui no Compass, quero excluir a coleção do usuário porque todos os usuários que temos até agora têm senha em texto simples Então exclua. Tudo bem. Agora, de volta ao terminal, vamos executar o mod Node. E então aqui no Postman, vamos enviar uma nova solicitação S. Linda. Então, aqui temos um novo usuário. Agora, de volta ao Compass, vamos atualizar a lista Temos a coleção do usuário, e aqui está nosso novo usuário com uma senha criptografada Linda. Então, implementamos esse endpoint para registrar novos usuários Nós terminamos aqui. A seguir, analisaremos a autenticação de usuários 7. Autenticando usuários: Tudo bem, então aqui na pasta de rotas, vamos adicionar um novo arquivo. Chamamos isso de logins dojs ou auth dot js. Qualquer um deles funciona, mas a autenticação é mais comum. Então, autentique-nos. Novamente, você economiza tempo, vou pegar um código emprestado Então, vamos até os usuários dot js. Vou copiar todo o código que escrevemos nesta seção e depois colar em auth dot js Agora, antes de entrarmos nos detalhes, vamos ao index dot JS. Na torneira, importe esse novo módulo. Então, Cs OT, configuramos isso para exigir rotas OT. Portanto, se tivermos alguma solicitação para esse endpoint, cortar a API OT ou um de seus endpoints secundários, delegaremos isso ao roteador Então, o panorama geral está pronto. Agora vamos dar uma olhada nos detalhes. Então, de volta ao módulo Auth, na parte superior, primeiro, precisamos validar o corpo da solicitação Mas essa função de validação que temos aqui é a que importamos do nosso módulo de usuário Então, isso está validando isso. No corpo da solicitação, temos três propriedades, nome, e-mail e senha. E no aplicativo do mundo real, você pode ter outras propriedades como parte do registro de um usuário Portanto, essa função de validação serve para validar um novo usuário. Não é para validar o e-mail e senha que esperamos neste endpoint Então, aqui precisamos de uma função de validação diferente. Então, vou remover essa função de validação daqui e definir uma função de validação separada neste módulo Agora, para economizar tempo, vou para o módulo do usuário e copiarei essa função de validação Portanto, validamos o usuário. Vamos copiar isso de volta para o módulo Auth, colá-lo aqui e, em seguida, alterá-lo para validar Agora podemos alterar o parâmetro a ser solicitado. Agora, para esse objeto de esquema, precisamos apenas de duas propriedades, e-mail e senha Então, vamos excluir o nome e pronto. Então, voltando ao nosso manipulador de rotas, esta é nossa primeira validação Em seguida, precisamos ter certeza que temos um usuário com um determinado e-mail. Então, carregamos o usuário. Se não tivermos o usuário , aqui aplicamos o operador not. Se não tivermos o usuário, devemos enviar um erro 400 ao cliente, o que significa que a solicitação e a mensagem devem ser um e-mail ou senha inválidos Observe que aqui, não estou enviando um quatro ou quatro, o que significa não encontrado porque não queremos dizer ao cliente por que a autenticação falhou. Não queremos saber se esse e-mail ou a senha estão corretos. Portanto, não queremos dizer que não temos um usuário com um determinado e-mail. Nós apenas dizemos ao cliente que essa é uma solicitação incorreta. Ele não tem os dados corretos para serem processados. Portanto, isso é para validar o nome de usuário e o e-mail neste caso Em seguida, precisamos validar a senha. Para isso, precisamos usar o BCRP. Então, vamos deletar todo esse código. Esse objeto da cripta B que temos tem um método de comparação. Usamos isso para comparar uma senha de texto simples com uma senha com hash Portanto, nossa senha de texto simples está na senha de ponto do corpo do ponto da solicitação, e nossa senha hash está no usuário dessa senha Então, como você viu anteriormente, essa senha hash inclui o SLT Então, quando chamamos o método de comparação, B crypt pega esse sal e o usa para restaurar essa senha de texto simples Se forem iguais, isso retornará verdadeiro. Então, aqui precisamos aguardar essa promessa e armazenar o resultado aqui em uma senha válida Agora, se a senha não for válida, novamente, retornaremos um erro 400 com essa mensagem vaga, e-mail ou senha inválidos Então, vou copiar isso e colar aqui. E, finalmente, se chegarmos até aqui, isso significa que esse é um login válido. Então, por enquanto, eu só quero enviar um valor simples e verdadeiro para o lint. 8. Testando a autenticação: Então, por enquanto, vamos testar essa rota de autenticação. Antes disso, então um ponto é. Aqui, esqueci de mencionar load joy. Então, deixe-me fazer isso rapidamente. Last Joy, defina isso para exigir Joy. Ok. E na parte inferior da função de validação, aqui precisamos retornar a solicitação de validação de pontos do esquema Ok, então estamos prontos. Vamos abrir o postmin. Então, aqui vou abrir uma nova guia. Vamos selecionar a postagem aqui. Deixe-me digitar o endpoint. É TP, host local OT, API OT. E no corpo da solicitação, vou enviar o GSN. Então, deixe-me selecionar Json aqui. E agora temos dois parâmetros. Então, o primeiro é o e-mail. O e-mail que usamos é 23, quatro, cinco, seis, sete, na taxa gmail.com E nossa senha é um, dois, três, quatro, cinco. Então, deixe-me enviar esse pedido, SN. Linda. Temos um status 200. Ok. E aqui está nossa resposta. Agora, deixe-me alterar a senha aqui para algo como 67 e depois enviar a solicitação novamente. Veja, temos uma solicitação inválida de 400 e o comando genérico, que é e-mail ou senha inválidos Agora, vamos alterar o e-mail para outra coisa com a senha correta. Então, algo assim. E deixe-me enviar o pedido novamente. Então mande. Veja, novamente, temos uma solicitação inválida de 400 e a mensagem genérica que é e-mail ou senha inválidos Portanto, nosso endpoint de autenticação está funcionando bem. Na próxima palestra, veremos a resposta que estamos enviando aqui e a alteraremos para algo que chamamos de token da web adjacente 9. Tokens da Web JSON: Portanto, temos um endpoint para autenticar usuários. Agora, precisamos modificar a resposta aqui e, em vez de retornar um valor verdadeiro, precisamos retornar um token web JCN webtoken AJCN é basicamente uma longa string que identifica Como metáfora, você pode pensar nisso como sua carteira de motorista ou seu passaporte É muito parecido com isso. Então, quando o usuário faz login no servidor, usamos esse token web JCN, que é como uma carteira de motorista ou passaporte, nós o entregamos ao cliente e dizemos a ele: Ei, próxima vez que você quiser voltar aqui e ligar para um de nossos endpoints de API, você precisará mostrar Você precisa mostrar sua carteira de motorista. Esta é a sua identidade. Então, no cliente, precisamos armazenar esse token web JCN, que é uma sequência longa, para que possamos enviá-lo de volta ao servidor para futuras chamadas de API Agora, o cliente pode ser um aplicativo web ou um aplicativo móvel. Se for um aplicativo web, se você estiver criando um aplicativo com angular ou react, poderá usar o armazenamento local. Esse é um local de armazenamento especial que está disponível em todos os navegadores existentes. Se você estiver criando um aplicativo móvel, você tem uma opção semelhante dependendo da plataforma que você usa. Então, agora deixe-me mostrar um exemplo de AJCnwbtken. Vá até o ponto II. Neste site, temos aqui um depurador para trabalhar com JS Então, aqui na seção codificada, você pode ver um exemplo real do token Web AJCN Essa longa string que você vê na seção codificada representa um JCNobr, então, quando decodificarmos isso, obteremos Está bem? Agora podemos ver que essa string tem três partes, e cada parte é um código de cores. Então, a primeira parte é vermelha, a segunda parte é roxa e a terceira parte é azul. No lado direito, você pode ver essa string decodificada. Portanto, a parte vermelha é o que chamamos de cabeçalho de um token web JCN Neste cabeçalho, temos duas propriedades. Um é L, que é a abreviação de algoritmo que determina o algoritmo usado para codificar esse token O tipo é GWT, que é o token da web JCN Agora, nunca mais precisamos nos preocupar com esse cabeçalho. É só um padrão. O que importa para nós é a segunda parte, a carga útil, que é a parte roxa Então, aqui temos um objeto JCN com três propriedades, sub, que é como um ID de usuário, nome e administrador Agora, a carga útil que você vê é diferente da carga que eu tenho porque modifiquei a pasta JS e o webtog e ela está Então eu gerei um token web personalizado, coloquei-o aqui. O que eu quero destacar aqui é que essa carga inclui propriedades públicas sobre o usuário Assim como no seu passaporte, você tem algumas propriedades sobre si mesmo, como seu nome, sua data de nascimento, seu local de nascimento e assim por diante Portanto, temos exatamente o mesmo conceito em token da web adjacente. Pode incluir algumas propriedades públicas básicas sobre o usuário. E com isso, toda vez que enviamos um token do cliente para o servidor, podemos facilmente extrair o ID do usuário da carga Se precisarmos saber o nome do usuário , podemos simplesmente extraí-lo aqui também. Não precisamos consultar o banco de dados, enviar esse ID para obter um objeto de usuário e depois extrair a propriedade name. Da mesma forma, se você quiser saber se o usuário é administrador ou não, podemos incluir isso aqui. Então, novamente, não precisamos enviar uma consulta extra ao banco de dados para ver se o usuário com um determinado ID é administrador ou não. Agora, você pode estar preocupado com essa abordagem do ponto de vista da segurança, porque pode pensar que qualquer pessoa pode simplesmente definir essa propriedade de administrador como verdadeira e, em seguida, será tratada como administrador no servidor. Mas não é assim que os ptocanos de Jason funcionam. A terceira parte desse token JCN Web, que está em azul, é uma assinatura digital Essa assinatura digital é criada com base no conteúdo deste JCN WebTken junto com uma chave secreta ou privada A chave secreta ou privada só está disponível no servidor. Portanto, se um usuário mal-intencionado obtiver o JCN WebTKen e modificar a propriedade do administrador, a assinatura digital será inválida porque o conteúdo do JCN Agora precisamos de uma nova assinatura digital, mas o hacker não pode gerar essa assinatura digital porque precisará da chave privada, que só está disponível no servidor Portanto, se eles não tiverem acesso ao servidor, não poderão criar uma assinatura digital válida. E quando eles enviarem esse token JCN Web temperado para o servidor, o servidor o recusará O servidor dirá que esse não é um token web JCN válido. Então é assim que os tokens JCN Web funcionam. 10. Gerando tokens de autenticação: Então, nesta página, se você olhar as bibliotecas, aqui você encontrará diferentes módulos ou bibliotecas para diferentes plataformas. Então, se você rolar para baixo, verá que Tad net one C B, C, C plus plus, node e assim por diante Então, vamos abrir o terminal e instalar o JCN webtook e o BM e instalar o ASN Ok, se você olhar o pacote em JSON, verá que a versão que estamos usando é 9.0 0.2 Então, vamos fechar isso. Temos o caminho para autenticar usuários. Agora, precisamos criar um JCN WebTken antes de enviar uma resposta ao cliente Então, antes disso, você precisa carregar o JCN WebTken. Então, no topo, exija que Jason rep, engasgue e armazene em uma constante chamada Ótimo. Agora, aqui, usaremos o método senoidal do JWT. Portanto, JW não seno, então aceitará dois argumentos. primeiro é a carga útil e o segundo é o rei secreto ou privado Portanto, a carga útil pode ser uma string simples ou pode ser um objeto como o que você vê aqui Então, vamos criar nosso objeto com apenas uma propriedade. Incluiremos o ID de sublinhado e o enviaremos para o ID de sublinhado de pontos do usuário Agora, de acordo com o segundo argumento, enviaremos isso para uma string. Mas, idealmente, você não deve armazenar sua chave secreta ou privada em seu código-fonte. Posteriormente, mostrarei como armazenar isso em um ambiente onde o. Mas, por enquanto, vamos colocar isso no segredo do JWT Não precisa ser uma chave secreta do JWT. Pode ser qualquer coisa, qualquer corda. Mas, por enquanto, vamos usar isso. Então, usamos um método de sinal e, como resultado, obtemos um token. Então, vamos armazená-lo constantemente e chamá-lo de token. E agora retornaremos ou enviaremos a resposta ao nosso cliente como um gancho. Então, há isso de volta ao terminal. Vamos seguir em frente. Agora, vamos ao carteiro. Aqui, enviaremos o e-mail e a senha corretos para essa rota de autenticação. Então, vamos enviar isso. E aqui está nosso token web JCN. Então, deixe-me copiar isso. E vamos voltar ao depurador. Nesta seção codificada, você pode simplesmente excluir esta e colar a que copiamos E aqui, na seção decodificada, você pode ver nosso objeto que enviamos como um token, então aqui temos a propriedade ID, que é definida como a ID do objeto no banco de dados Mongaim Além disso, temos o IAT, que é a hora atual e a hora em que esse token é criado Isso é usado para H do token. Portanto, criamos o token com sucesso e o enviamos como uma resposta ao nosso clima. No próximo vídeo, mostrarei como incluir essa chave secreta em uma variável de ambiente. 11. Armazenando segredos em variáveis de ambiente: No início do curso, quando eu estava falando sobre tópicos avançados do Express, apresentei a você um pacote de nós chamado Config Usamos esse pacote para armazenar as configurações do nosso aplicativo em arquivos JSON ou variáveis de ambiente Então, nesta palestra, vamos pegar essa chave secreta e armazená-la em uma variável de ambiente porque, como eu disse antes, você nunca deve armazenar seus segredos em sua base de código Caso contrário, esses segredos serão visíveis para qualquer pessoa que tenha acesso à sua fonte. Então, de volta ao terminal, vamos instalar o módulo de configuração Posso observar o número da versão que é 3.3 0.11. Agora, primeiro, precisamos criar uma nova pasta que seja config. Nessa pasta, adicionamos um arquivo de configuração padrão que é o ponto padrão JSM Então, um objeto SN simples. Poderíamos ter várias configurações aqui. Mas, por enquanto, eu só quero adicionar uma configuração. Essa é a chave secreta do JWT. Agora, neste arquivo GSN padrão, vamos definir isso como uma string vazia O valor real não está aqui. Então, aqui estamos apenas definindo um modelo para todas as configurações em nosso aplicativo. Agora precisamos criar outro arquivo com variáveis de ambiente personalizadas dot JS. Observe a ortografia, certifique-se de acertar. Caso contrário, o que vou mostrar nesta palestra não funcionará em sua máquina Então, como eu disse antes, neste arquivo, especificamos o mapeamento entre as configurações do nosso aplicativo e as variáveis de ambiente. Então, vou voltar ao nosso ponto padrão Son, copiar tudo isso e colar aqui. Portanto, essa é a estrutura do nosso objeto de configuração do aplicativo. Agora, queremos mapear isso para uma configuração para uma variável de ambiente chamada chave secreta JWT Mas, como prática recomendada, novamente, como eu disse antes, é melhor prefixar isso com nome do nosso aplicativo para que você não acabe com uma configuração do aplicativo substituindo outra configuração do aplicativo Portanto, rodas justas alinham a chave secreta do JWT. Agora, com isso, podemos voltar ao nosso módulo Auth, então Js. Então, este é um lugar onde referenciamos o segredo. Vamos substituí-lo por uma chamada para o método Confic dot get Então, primeiro na parte superior, precisamos importar o objeto de configuração. Então, configuração do Cs. Definimos isso para exigir confit. Ok. Agora, de volta ao método post, chamamos config dot cat e passamos o nome da configuração do aplicativo Nesse caso, o segredo do JWT K. Então, agora, isso não é um segredo. É o nome da configuração do nosso aplicativo. O valor real, o segredo real estará em uma variável de ambiente. Uma última mudança, precisamos ir para index dot js. Quando o aplicativo é iniciado, você deseja garantir que essa variável de ambiente esteja definida. Caso contrário, teremos que encerrar o aplicativo porque nosso endpoint de autenticação não pode funcionar corretamente Mais uma vez, na parte superior, carregamos o módulo de configuração Config, definimos isso para exigir configuração. Agora, mais uma vez, vamos chamar config dot get pass o nome da chave secreta JWT de configuração do aplicativo Agora, se isso não estiver definido, registraremos um erro fatal. A chave secreta do JWT não está definida. E então precisamos sair do processo. Anteriormente, você aprende sobre esse objeto de processo. Esse é um dos objetos globais no node. Aqui temos um método chamado exit. Nós lhe damos um código, zero indica sucesso. Qualquer coisa menos zero significa fracasso. Muitas vezes, usamos exit one se você quiser sair do processo em caso de erro. Então, atualmente, eu não configurei essa variável de ambiente. Vamos executar o aplicativo e ver o que acontece. Então Norman index dot JS, ok, olha, temos esse erro fatal O aplicativo travou, aguardando alterações no arquivo antes de começar. Agora você pode pensar que o aplicativo ainda está em execução porque Norman ainda está lá Não foi encerrado. Mas se você for ao Postman e enviar uma solicitação de SDDP para o aplicativo, verá que nosso aplicativo não está Então, se o aplicativo falhar, Norman ainda está trabalhando Norman ainda está correndo. Deixe-me mostrar o que quero dizer. Então, se, em vez de não modificar, eu executar o aplicativo com o nó, vejo que o aplicativo travou e agora estamos de volta ao terminal Portanto, não estamos respondendo a nenhuma solicitação recebida dos clientes Agora, vamos definir a variável de ambiente. Como eu disse antes, no Mac, você usa Export, no Windows, você usa set para prompt de comando e coluna dollar ENV para Power Shell Coluna Dollar ENV, rodas justas, sublinhado, chave secreta da JWT. Nós definimos isso também. Digamos que minha chave segura. Agora vamos executar o aplicativo novamente. Índice de nós ou Js. Ok, lindo. Nós o conectamos ao Mongadib e, se voltarmos ao Postman e enviarmos outra solicitação ao Login, aqui está nosso cheese válido e token da web que são assinados com nossa chave secreta, que é armazenada em 12. Definindo cabeçalhos de resposta: Portanto, na implementação atual, quando o usuário faz login, geramos um token web JCN e o retornamos no corpo da resposta Agora, vamos levar esse aplicativo para o próximo nível. Vamos imaginar que, quando o usuário se registra, queremos supor que ele esteja logado, para que ele não precise fazer login separadamente Obviamente, esse requisito não se aplica a todos os aplicativos. Às vezes, você quer obrigar o usuário a verificar seu endereço de e-mail Então, depois que eles se inscreverem, você envia um e-mail e eles clicam em um link. Portanto, o processo é diferente. Mas neste curso, vamos imaginar que o Fair Wheels seja um aplicativo executado localmente em uma locadora de veículos. Portanto, as pessoas que usam esse aplicativo são pessoas que trabalham nesse aluguel de carros. Não precisamos verificar o endereço de e-mail deles. Então, no primeiro dia em que entram na loja, precisam criar uma conta e pronto, estão logados Então, vamos ao módulo do nosso usuário. Ok, aqui está o método de postagem. É aqui que registramos um novo usuário. Agora, se você observar a resposta que estamos retornando aqui, estamos retornando um objeto com essas três propriedades. Agora podemos adicionar o token web JCN como outra propriedade aqui, mas isso é um pouco feio porque não é propriedade de um Uma abordagem melhor é retornar o token web JCN em um cabeçalho SDDP Assim como temos cabeçalhos em nossa solicitação, também temos cabeçalhos em nosso objeto de resposta Então, vou voltar ao nosso módulo Auth e emprestada essa linha de código para gerar o token Então, copie isso agora de volta para o módulo do usuário. Antes de enviarmos a resposta ao cliente, geramos o token e seguida, chamamos um cabeçalho de ponto de resposta. Com isso, podemos definir um cabeçalho. Agora, para qualquer cabeçalho personalizado que definimos em nosso aplicativo, devemos prefixar esses cabeçalhos com X. Agora, damos a ele um nome arbitrário que definimos em nosso aplicativo, devemos prefixar esses cabeçalhos com X. Agora, damos a ele um nome arbitrário, como autenticação ou token. Esse é o primeiro argumento, que é o nome do cabeçalho. O segundo argumento é o valor, que, nesse caso, é nosso token. Então, com essa mudança simples, definimos esse cabeçalho e enviamos essa resposta ao cliente. Está bem? Agora, na linha 20, estamos usando o JWT, bem como o módulo confit Então, precisamos importá-los na parte superior. Então, um TWT constante, configuramos isso para exigir o token web JCN. E da mesma forma, configuração constante, definimos isso para exigir confit Agora vamos testar isso. Então, na última aula, executei o aplicativo com node em vez do modo nor Portanto, minhas alterações não são visíveis. Portanto, precisamos parar o aplicativo e executá-lo com o modo de nó. Ok, lindo. Agora, de volta ao Postman aqui nesta guia para registrar um usuário, vou mudar esse e-mail para um e-mail que eu não tenha registrado Enviado. Ok, dê uma olhada. Então, aqui está o corpo da resposta exatamente como antes. Agora, na aba Headertab Look, temos esse novo cabeçalho, o token X. E isso está configurado para o nosso JCN WebTken. Então, em nosso aplicativo cliente, quando registramos um usuário, podemos ler esse cabeçalho. Podemos armazenar esse JCN WebTgen no cliente. E da próxima vez que fizermos uma chamada de API, enviaremos isso para o servidor. 13. Encapsulando a lógica em modelos Mongoose: Agora, há um problema em nossa implementação atual. No módulo do usuário na linha 22, é assim que geramos um token web JCN Temos exatamente o mesmo núcleo no módulo Auth na linha 20. Agora, veja a carga útil desse token da web JCN. Nessa carga, atualmente, temos apenas a propriedade ID Provavelmente, amanhã adicionaremos outra propriedade a esse pagamento, talvez o nome do usuário, talvez seu endereço de e-mail, talvez sua função. Queremos saber se há um usuário administrador ou não. Com a implementação atual, toda vez que quisermos alterar essa carga, precisamos lembrar que precisamos ir para outro módulo e fazer exatamente a mesma alteração E, a longo prazo, você esquecerá esses requisitos. Então, nesta palestra, vou mostrar como encapsular essa lógica em um Agora, para onde devemos mover essa lógica? Um programador amador pode pensar: Ok, vou criar uma função como gerar token de autenticação, colocar essa função em algum lugar que possamos reutilizar, talvez em outro módulo que possamos importar nos módulos da Terra e do usuário E com isso, temos a lógica em um único lugar. Bem, isso é verdade. Isso funciona. Mas com essa abordagem, você acabará com muitas funções espalhadas por todo o lado. Na programação orientada a objetos, temos um princípio chamado princípio do especialista em informações. Isso significa um objeto que tem informações suficientes e é especialista em uma determinada área. Esse objeto deve ser responsável por tomar decisões e executar tarefas. Como exemplo do mundo real, pense em um chef. Um chef tem conhecimento de culinária. É por isso que o ato de cozinhar em um restaurante é feito por um chef e não por um garçom O garçom não tem o conhecimento certo, as informações certas sobre culinária em um restaurante Então, se o chef é um objeto, devemos dar o ato de cozinhar ao chef. Agora, pegue esse princípio e aplique-o neste código. Então, aqui, como parte da criação desse token Chase e da web, o que precisamos na carga útil Precisamos do ID do usuário. Amanhã, talvez precisemos do nome do usuário ou do e-mail dele. Então, todas essas informações estão encapsuladas aqui no objeto do usuário Portanto, é o objeto do usuário que deve ser responsável por gerar esse token de autenticação. Então, a função que eu escrevi aqui, gerar token de autenticação, essa função não deve estar pendurada em algum lugar em um módulo. Isso deve ser um método no objeto do usuário. Então, aqui temos um objeto de usuário que carregamos do banco de dados. Precisamos adicionar um método nesse objeto de usuário como esse. Usuário que gera o token de autenticação. E isso nos dará uma lembrança, simples assim. Agora, como podemos adicionar isso? Precisamos acessar nosso módulo de usuário, onde definimos o modelo do usuário e fazemos uma alteração simples nele. Tudo bem Então, aqui em nosso modelo de usuário, precisamos extrair a definição desse esquema e colocá-la em uma constante separada porque vamos trabalhar com esse esquema separado Então, vou selecionar todo esse código. Portanto, ao criar o modelo do usuário como segundo argumento, passamos o esquema do usuário e ainda não o criamos Nós vamos fazer isso agora. Então, esquema de usuário constante, e definimos isso para essa expressão assim Ok. Então, aqui está nosso esquema de usuário Agora, você deseja adicionar um método nesse esquema. Então, o esquema do usuário em que temos uma propriedade, métodos, isso retorna um objeto Podemos adicionar mais pares de valores-chave nesse objeto. Assim, podemos adicionar uma chave, gerar autenticação ou token. Definimos isso como uma função. Então, par de valores-chave. Quando fizermos isso, nosso objeto de usuário terá um método chamado generate authentication token. Agora, aqui, nesta função, podemos ter parâmetros. Então, se tivermos um parâmetro aqui, ao chamar esse método, podemos passar argumentos. Nesse caso, não precisamos de nenhum parâmetro, então eu só preciso pegar essa lógica para gerar o token, obtê-lo daqui e movê-lo dentro desse novo método. Então, aqui na carga, precisamos do D do usuário. Como podemos conseguir isso? Bem, esse método fará parte do objeto do usuário. Então, para referenciar o objeto em si, substituímos o usuário por isso. E isso significa que aqui você deve usar a sintaxe da função regular Você não pode substituir isso por uma função de seta. Porque, como eu disse antes, as funções de seta não têm nada a ver com isso. Isso em uma função de seta faz referência à função de chamada. Então, normalmente, usamos seta para funções autônomas Se você quiser criar um método que faça parte de um objeto, você não deve usar uma função de seta. Agora, vamos reverter isso. Então, aqui temos o token e, finalmente, o devolvemos tão simples quanto isso. Aqui estamos fazendo referência ao JWT e aos módulos de conflito. Então, precisamos importar isso na parte superior. Então, vou voltar ao nosso módulo Auth na parte superior. Não precisamos mais dessas declarações obrigatórias. Então, eu vou pegá-los daqui. E coloque-os em cima do módulo do usuário. Agora, de volta ao módulo de autenticação , geramos o token e o enviamos para o cliente. Precisamos fazer as mesmas alterações no módulo do nosso usuário. Módulo do usuário, excluímos essa linha e definimos o token para o usuário que gera AuthToken Então, finalmente, vamos testar isso e garantir que tudo esteja funcionando. Então, vou registrar um novo usuário aqui. Envie, linda. E aqui está nosso token de autenticação. 14. Middleware de autorização: Portanto, no início desta seção, decidimos proteger as operações que modificam os dados e os disponibilizam somente para usuários autenticados Então, vamos até nossas empresas, Dot CHASE Piers, o método de postagem para criar uma nova empresa Esse endpoint da API só deve ser chamado por um usuário autenticado. Então, como podemos impor isso? Bem, aqui, fizemos uma lógica como essa. Precisamos ler os cabeçalhos da solicitação. Portanto, esse objeto de solicitação tem um método chamado header. Aqui, especificamos o nome do cabeçalho, que é o token X. Esperamos um token web JCN armazenado nesse cabeçalho. Então, armazenamos isso como um token constante. Agora, queremos validar isso. Se isso for válido, concederemos acesso a esse endpoint da API Caso contrário, retornaremos uma resposta como essa. Resposta para o código de status de quatro em um, que significa que o cliente não tem as credenciais de autenticação para acessar esse recurso Então esse é o panorama geral. Agora, não queremos repetir essa lógica no início de cada manipulador de rotas que modifica dados Então, precisamos colocar essa lógica em uma função de middleware. Lembre-se, funções de middleware, falamos sobre elas na seção chamada Tópicos avançados do Express Então, colocamos essa lógica em uma função de middleware e, em seguida, podemos aplicar essa função em manipuladores de rotas que precisam modificar dados. Deixe-me te mostrar. Então, vamos tirar isso daqui. Tudo bem, aqui queremos adicionar uma nova pasta chamada middleware Então, colocamos todas as nossas funções de middleware aqui. Nessa pasta, tínhamos um novo arquivo t dot tem. Agora, aqui queremos definir uma função chamada OT que usa três parâmetros, resposta de solicitação e next, que usamos para passar o controle para a próxima função de middleware no pipeline de processamento de solicitações Se esse conceito parecer estranho para você, você precisa voltar para a seção chamada Express Advanced Topics, pois lá exploramos as funções de middleware Então, aqui nesta função, devemos implementar essa lógica. Nós recebemos o token. É provável que não tenhamos nenhum token. Nesse caso, retornamos uma resposta 41 com uma mensagem como essa. Acesso negado. Nenhum token fornecido. Portanto, isso ajuda o cliente a descobrir por que ele não pode acessar esse recurso. Agora, caso contrário, há um token. Precisamos verificar se esse é um token válido. Então, aqui precisamos usar nosso módulo de token JCN Web. Então, no topo, vamos exigir o token web JCN e armazená-lo no JW Agora, aqui chamamos jwt dot Verifi. Como primeiro argumento, passamos o token e, como segundo argumento, passamos a chave secreta para decodificar esse token Então, armazenamos essa chave secreta em uma variável de ambiente. Precisamos usar um módulo de configuração para lê-los. Portanto, exija a configuração e guarde-a aqui. Então, assim como antes, chamamos config dot g JWT Ccret key. Agora, esse método de verificação verificará Se for válido, ele o decodificará e retornará a carga útil. Então, aqui temos a carga decodificada. No entanto, se esse token não for válido, ele lançará uma exceção. Portanto, precisamos envolver essa linha com um bloco try cache. Então, experimente o Cache, temos uma exceção. Se chegarmos aqui, queremos dizer ao cliente que esse é um token inválido Definimos esse status como 400 porque há uma solicitação inválida porque o que o cliente nos envia não tem os dados corretos. Portanto, envie um token inválido. Novamente, com essa mensagem de erro, podemos solucionar os problemas de autenticação Portanto, se no cliente não conseguirmos acessar um determinado endpoint da API, veremos a mensagem de erro Percebemos que enviamos um token inválido. Em seguida, analisaremos a lógica do cliente em que obtemos o token e o enviamos para o servidor. Então esse é o nosso bloco de cache. Agora, de volta ao bloco triplo, aqui temos a folha de pagamento Então, podemos colocar isso na solicitação. Então, nosso objeto de solicitação, adicionamos a propriedade do usuário a ele e a definimos para essa decodificação Então, anteriormente, colocamos somente o ID do usuário na carga Deixe-me te mostrar. Então, vamos ao nosso módulo de usuário. Aqui está o esquema do nosso usuário. Adicionamos esse método de geração de token de autenticação. Criamos o JCN WebTken e essa é a nossa carga útil. Então, quando decodificamos esse JWT, esse é o objeto que obteremos E vamos colocar isso na solicitação como um objeto de usuário. Portanto, em nosso manipulador de rotas, podemos acessar request dot user dot underline dot ID e Está bem? Então, no bloco tri, definimos request dot user e, em seguida, precisamos passar o controle para a próxima função de middleware no pipeline de processamento de solicitações Nesse caso, esse é o nosso manipulador de rotas. Então, ligamos em seguida. Então, como eu disse antes, nas funções de middleware, encerramos o ciclo sl de resposta da solicitação ou passamos o controle para a próxima Agora, apenas um pequeno problema nesse código, caso não tenhamos um token, enviaremos essa resposta ao cliente. Mas quero ter certeza de que saímos dessa função. Tudo bem, terminamos com nossa função de middleware. Agora, no final, configuramos as exportações de pontos do módulo para OTO, um atalho para isso é configurá-lo aqui Então, definimos as exportações de pontos do módulo, configuramos isso como uma função. Não precisamos de um em aqui. E então podemos nos livrar da linha 17. Feito. 15. Protegendo rotas: Então, agora que temos uma função de middleware, podemos ir para index dot JS, olha, aqui estamos aplicando funções de middleware Portanto, podemos adicionar isso aqui e, em seguida, ele será executado antes de cada manipulador de rotas Mas não queremos fazer isso porque nem todos os endpoints da API devem ser protegidos Alguns de nossos endpoints de API devem ser públicos, como registrar um usuário, fazer login ou obter a lista de empresas ou clientes Portanto, nesse caso, queremos aplicar essa função de middleware seletivamente a Então, voltando ao módulo da empresa, aqui está nosso gerenciador de rotas de postagem O primeiro argumento é uma rota. O segundo é opcionalmente o middleware e o terceiro será o verdadeiro manipulador de rotas Então, vamos ao topo, transmitir essa função de middleware . Então exija. Agora precisamos subir um nível e depois ir para a pasta do middleware e carregar o módulo Earth Nós pegamos e colocamos aqui. E finalmente, aqui no método post, passamos a OT como uma função de middleware a ser executada antes dessa outra função de middleware, que é, neste caso, Então, agora vamos testar isso de volta no Postman. Vou abrir uma nova guia e enviar uma solicitação de postagem para o endpoint da empresa Então, hospedeiro local do STDP, empresas de API. Agora, nesse caso, não estou preocupado com o corpo da solicitação. Só quero saber se podemos chamar esse endpoint da API ou não Então envie Ok, olha, temos esse erro 401 ou não autorizado E aqui está a mensagem de erro. Acesso negado, Noto pode fornecer. Agora, vamos fornecer um token inválido. Então, vamos para a guia de cabeçalhos, definimos a chave que é o token X. Eu coloquei um token inválido, enviei, recebemos 400 ou uma solicitação inválida com esta mensagem Token inválido. Linda. Agora, finalmente, vamos voltar ao nosso registro, use uma guia. Temos um token de autenticação válido. Então, vamos copiar isso de volta para a terceira guia. Coloque-o aqui e depois envie. Ok, agora recebemos uma solicitação incorreta, mas isso não é por causa da autenticação. Isso ocorre porque esperávamos a propriedade name no corpo da solicitação. Então, se eu adicionar um objeto JSON aqui no corpo, nomeie uma nova empresa Agora, devemos estar bem. Enviar. Então, recebemos uma resposta de 200, e esta é a nova empresa. Então, como exercício, quero que você aplique essa função de middleware a outros manipuladores de rotas que 16. Obtendo o usuário atual: Em muitos aplicativos, às vezes precisamos obter informações sobre o usuário atualmente conectado Então, nesta palestra, vamos adicionar um novo endpoint de API para obter o usuário atual Então, vamos ao nosso módulo de usuários. Atualmente, temos apenas um manipulador de rotas. Isso é para criar um novo usuário. Agora precisamos adicionar outro manipulador para obter métodos. Agora, aqui, adicione um caminho ou rota. Podemos passar um parâmetro, mas isso significa que o cliente deve enviar o ID para o servidor. Embora essa abordagem seja perfeitamente adequada, às vezes, talvez por motivos de segurança, você não queira ter um endpoint como esse, porque então eu posso enviar a ID de outro usuário e ver a conta dele, onde pode haver algumas informações que talvez não devessem estar visíveis para mim Portanto, a abordagem que usamos com bastante frequência para obter informações sobre o usuário atual é ter um endpoint de API como eu Com isso, o cliente não enviará o ID do usuário. Nós o obtemos da fonte JCN Web. Portanto, não posso falsificar JCN WebTken de outra pessoa porque eu disse que , para fazer isso, preciso criar uma nova assinatura digital para o JCN WebTken de outra pessoa porque eu disse que , para fazer isso, preciso criar uma nova assinatura digital para esse JCN WebTken. Então, vamos adicionar o manipulador de rotas, solicitação assíncrona e a resposta vão para esse bloco Agora, esse endpoint da API só deve estar disponível para usuários autenticados. Então, aqui precisamos adicionar nosso middleware de OT. Na parte superior, vamos carregar o OT a partir do middleware Auth. Só para esclarecer, aqui, autor representa autorização, não autenticação, porque a autenticação trata de validar a senha do nome de usuário Aqui, queremos ver se o usuário tem permissão para acessar um recurso ou não, e isso é autorização. Adicionamos nosso middleware aqui. Agora, com esse middleware, se um cliente não enviar um token web JCN válido, nunca chegaremos a esse No entanto, se você chegar aqui, como viu na implementação dessa função de middleware aqui, teremos request dot user object Assim, podemos acessar a propriedade ID aqui. Então, em vez de passar a propriedade ID no caminho ou na rota, nós a obtemos da solicitação dot user dot ID, que na verdade vem do nosso token web JSON Portanto, essa é uma abordagem mais segura. Agora, queremos encontrar um usuário pelo ID fornecido. Então, chamamos o usuário dot fine por ID. Pré-passe esse valor , aguarde a promessa e obtenha o objeto do usuário aqui Agora, não queremos devolver a senha do usuário ao cliente. Então, aqui, vamos chamar Selecionar e excluir a propriedade da senha. Em seu aplicativo, talvez você também queira excluir outras propriedades. Talvez endereço, talvez número de telefone. Então, aqui temos um objeto de usuário. Finalmente, enviamos isso para o cliente. Então, envie ao usuário de forma tão simples quanto isso. Agora, vamos testar isso. Então, aqui no Postman, vou adicionar uma nova guia, enviar uma solicitação Get para o host local para 3.000 usuários da API para Agora, inicialmente, eu não quero enviar um JCN WebTken. Portanto, envie Xs negados sem token, fornecido. Linda. Agora vamos para a guia de cabeçalhos. Adicione X ou token aqui e, em seguida, passe um queijo casado e um token web SN. Esta é minha conta de usuário. Podemos ver que a senha está excluída. 17. Desconectando usuários: Então, em nosso módulo Auth, definimos essa rota para autenticar usuários Que tal desconectar usuários? Precisamos de uma rota separada para isso? Não, porque não estamos armazenando esse token em nenhum lugar do servidor. Portanto, não precisamos de um manipulador de rotas separado para excluir esse token Então, tecnicamente, você precisa implementar o recurso de desconexão no cliente, não no servidor Portanto, no aplicativo cliente, quando o usuário quiser sair, basta excluir esse token do cliente. Agora, eu vi cursos e tutoriais que ensinam você a armazenar esse token no servidor no banco Essa é uma prática muito ruim porque esses tokens são como chaves que dão ao cliente acesso a endpoints de API protegidos Se um hacker conseguir acessar seu banco de dados, ele poderá ver todos esses tokens para usuários autenticados Eles nem precisam saber a senha de um usuário. Eles podem simplesmente obter seu token de autenticação e enviá-lo ao servidor para executar a solicitação em nome de um usuário. Você não deve armazenar tokens em seu banco de dados. E se você sabe o que está fazendo e realmente deseja armazenar o token no banco de dados, certifique-se de criptografá-lo. Certifique-se de fazer um hash. Assim como as senhas. Armazenar um token em um texto simples no banco de dados é como obter o passaporte ou a carteira de motorista de todos os usuários, colocá-los em um local central e, em seguida, qualquer usuário mal-intencionado que tenha acesso a esse local central pode simplesmente obter esses passaportes Eles podem obter essas carteiras de motorista e imitar outros usuários, outros clientes Então, mais uma vez, não armazene os tokens no servidor, armazene-os no cliente. E como prática recomendada de segurança, sempre que você estiver enviando o token do cliente para o servidor, certifique-se de usar HTTPS. Portanto, um hacker sentado no meio do tráfego não consegue ler o token enviado do cliente para o servidor, então os dados são criptografados entre o cliente e o 18. Autorização baseada em funções: Até agora, implementamos a autenticação e a autorização com sucesso. Agora vamos levar esse aplicativo para o próximo nível. Vamos imaginar que certas operações, como excluir dados, só possam ser realizadas por administradores Então, deixe-me mostrar como implementar uma autorização baseada em funções. Primeiro, precisamos acessar nosso modelo de usuário. Portanto, esse é o nosso esquema de usuário. Atualmente, temos três propriedades, nome, e-mail e senha. Agora, precisamos adicionar outra propriedade para ver se um determinado usuário é administrador ou não. Então, vamos adicionar uma nova propriedade admin do tipo Boolean. Então esse é o primeiro passo. Agora vou entrar no Mongo DB Compass, pegar um desses usuários e torná-lo administrador. Então edite. Vou adicionar um campo após a senha, e a ordem realmente não importa. O mesmo acontece com admin e, por padrão, você pode ver que o tipo disso é string. Vamos mudar isso para Boolean. Então, vamos dizer que isso é verdade e , finalmente, aplicar a atualização. Então, aqui eu tenho um usuário que é administrador. Agora, ao fazer o login, quero incluir essa propriedade em nosso payload do JSON Web Token Então, da próxima vez que eles enviarem esse JCN WebTken para o servidor, poderemos extrair essa propriedade diretamente do Não precisamos obter o ID, entrar no banco de dados e ver se eles são administradores ou não. E, novamente, como eu disse antes, com a assinatura digital incluída em um webtken da JCN, um usuário mal-intencionado não pode alterar o valor de seu administrador para sua conta Se eles fizerem alguma alteração, precisarão regenerar a assinatura digital, e isso requer conhecer a chave privada que armazenamos em uma variável de ambiente no servidor Agora, de volta ao nosso módulo de usuário, quando geramos o token de autenticação, queremos adicionar essa propriedade na carga Então, aqui está nossa carga útil. Vamos adicionar uma nova propriedade como administrador. Nós configuramos isso para. Esse dt é Admin. Portanto, esse é o benefício de encapsular essa lógica dentro do objeto do usuário Portanto, há um único lugar que precisamos modificar. Anteriormente, tínhamos isso em dois lugares diferentes. E com essa mudança de símbolo, tivemos que lembrar de aplicar essa alteração em dois lugares diferentes no código. Então esta é a nossa joelheira. Agora, no servidor, precisamos uma nova função de middleware para verificar se o usuário atual é administrador ou Então, aqui na pasta de middleware, vou adicionar um novo arquivo, admin Então, aqui configuramos o módulo que exporta para uma função de middleware E recebe uma solicitação, uma resposta e uma referência à próxima função de middleware no pipeline de processamento de solicitações Então, aqui estamos assumindo que essa função de middleware será executada após nossa função será executada após de middleware de autorização Portanto, nossa função de middleware de autorização define solicitação, não o usuário, para que possamos acessá-la nesta Então, solicito que o usuário que é administrador, ou digamos que, se ele não for administrador, retornaremos o status de resposta. Definimos o status 24 em três, o que é proibido. Essa é uma das áreas em que muitos desenvolvedores erram. Então, temos 41, o que significa não autorizado, e temos quatro e três, o que significa proibido Usamos não autorizado quando o usuário tenta acessar um recurso protegido, mas ele não fornece um JSN WebKen válido Então, damos a eles a chance de tentar novamente e enviar um JCN WebKen válido agora Se enviarem um token web GSN válido e ainda não tiverem permissão para acessar o recurso de destino, é quando usamos quatro e três, o que significa proibido, o que significa não tente novamente, simplesmente não podemos acessar esse que significa proibido, o que significa não tente novamente, simplesmente não podemos Então, aqui, definimos o status e enviamos uma mensagem como acesso negado. Agora, caso contrário, se o usuário for administrador, passaremos o controle para a próxima função de middleware, que é, nesse caso, o manipulador de rotas Agora vamos aplicar essa função de middleware em uma de nossas rotas. Então, voltando às empresas dot JS, vamos dar uma olhada no método delete. Então, aqui está nosso método de exclusão. Queremos aplicar duas funções de middleware aqui. Então, precisamos passar uma matriz. O primeiro é OT e o segundo é administrador. Portanto, essas funções de middleware serão executadas em sequência Primeira parte, se o cliente enviar um Jas variado no webtken, depois chegaremos à segunda função de milware O usuário é administrador e, em seguida, a terceira função de middleware ou manipulador de rotas será executada Agora, precisamos importar isso no TA. Portanto, como administrador constante, configuramos isso para exigir que você acesse a pasta do middleware e carregue o módulo de administração Agora, vamos testar isso. De volta ao Postman Vou abrir uma nova guia e enviar uma solicitação de exclusão para esse endpoint, host local STDP para 3.000 Agora, deixe-me pegar uma identificação de uma empresa do banco de dados Mongo IV. Então vá para Companies Collection, aqui, copie esse ID e coloque-o em nosso endpoint desta forma Não se esqueça de incluir o token de probabilidades. Caso contrário, você receberá o erro de autorização. Excesso negado, nenhum token o fornece. Então, vamos colocar o token e agora enviá-lo. Linda. Temos uma resposta de 200, e aqui está a empresa que foi excluída.