Aula 09 – Golang – Fiber – Register User
Aula 09 – Golang – Fiber – Register User
Voltar para página principal do site
Todas as aulas desse curso
Aula 08 Aula 10
Redes Sociais:
Link para a Digital Innovation
Quer aprender python3 de graça e com certificado? Acesse então:
workover
Meus link de afiliados:
Hostinger
Digital Ocean
One.com
Código da aula: Github
Melhore seu NETWORKING
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no GITHUB.
Canais do Youtube
Toti
Backing Track / Play-Along
Código Fluente
Putz!
Vocal Techniques and Exercises
PIX para doações
Aula 09 – Golang – Fiber – Register User
Nessa aula vamos adicionar o pacote bcrypt para poder fazer o hash do password do usuário, para isso acesse: pkg.go.dev
E pesquise bcrypt, aí então é só escolher a primeira opção que aparece.
Instalando bcrypt no projeto
Se o projeto tiver rodando, pare ele e instale com:
go get -u golang.org/x/crypto/bcrypt
Bcrypt é um padrão da indústria testado e comprovado para resistir a ameaças de hackers e outros agentes mal-intencionados.
O que ele faz é aplicar uma funçao de hash na senha em texto puro, para depois, na hora de armazenar, salvar no banco só o hash gerado e não a senha original.
A ideia por trás do hash de senhas dos usuários, é deixar as passwords seguras contra ataques de hackers, ou qualquer tipo de invasão de sistema, enfim, qualquer ação maliciosa.
Há 3 formas que as empresas armazenam as passwords: texto puro(plain text), encriptografando a senha, ou usando uma função de hash.
Texto puro
Texto puro é obviamente a maneira mais perigosa de armazenar senhas.
Se hackers violarem o banco de dados da empresa, eles conseguem ver todas as senhas dos usuários.
Muitas pessoas têm o mau hábito de usar a mesma senha para várias contas, é provável que 1 senha comprometida pode levar a mais contas comprometidas.
Encriptografando a senha
Uma alternativa possível ao armazenamento de texto puro é a criptografia.
As empresas pegam as senhas dos usuários e antes de armazenar, criptografa elas com uma chave.
Isso impediria que hackers obtivessem as senhas reais dos usuários, mas ainda é muito arriscado.
Na camada de criptografia ainda é uma senha de texto puro e por isso se o invasor consegue roubar a chave de criptografia também, ele pode desbloquear todas as senhas.
A criptografia foi projetada para funcionar de duas maneiras: você pode criptografar as senhas de um usuário para manter ela segura, mas, você também pode descriptografá-la para revelar a senha novamente.
Isso é muito prático quando você quer compartilhar dados de forma segura, mas não é bom se você quer impedir que invasores violem sua senha.
Isso nos leva à terceira técnica de armazenar senhas que é usando função de hash.
Função de Hash
Como funciona?
As funções hash pega uma entrada, que pode ser um texto como senha ou um arquivo, e transforma em uma string de texto sempre com o mesmo comprimento.
Existem muitas funções diferentes de hash disponíveis: MD4, MD5, SHA-1, WHIRLPOOL, etc.
As funções de hash são muito diferentes da criptografia porque elas só funcionam unidirecionamente.
Você pode calcular o hash de uma senha, mas você não pode pegar um hash e transformá-lo de volta aos dados originais.
Ao usar hashes, as empresas podem verificar se você está logando com a senha correta, sem ter que armazenar sua senha real.
No entanto, elas não são perfeitas também.
A maioria dos algoritmos de hashing são otimizados para velocidade, quanto mais hashes por segundo, melhor e mais seguro é o hash que elas podem calcular.
Mas de qualquer forma, existe uma vulnerabilidade a ataques de força bruta.
O hacker pode simplesmente tentar calcular todas as senhas possíveis, e conseguir reverter o hash.
Uma GPU moderna pode fazer isso com uma velocidade de 292 milhões de hashes por segundo (292,2 MH/s), é só uma questão de tempo antes de uma senha hash ser quebrada usando essa técnica.
E se isso não for rápido o suficiente, hackers também podem usar rainbow table para acelerar o processo.
Estas são listas de hashes pré-computados que podem ser usadas para encontrar rapidamente senhas fracas e comumente usadas.
Veja na ilustração abaixo como funciona a função de hash.
Veja a tabela abaixo, mostrando a aplicação da função de hash MD5 nas senhas: a, ab, abc, e abc1.
Perceba que o hash gerado é sempre do mesmo tamanho, independente do tamanho da senha.
Vamos importar o bcrypt e usar para fazer o hash da senha com o custo de 14 para gerar o hash.
fiber-project/controllers/authController.go
package controllers
import (
"fiber-project/models"
"github.com/gofiber/fiber/v2"
"golang.org/x/crypto/bcrypt"
)
func Register(c *fiber.Ctx) error {
var data map[string]string
if err := c.BodyParser(&data); err != nil {
return err
}
if data["password"] != data["confirm_password"] {
c.Status(400)
return c.JSON(fiber.Map{
"message": "Passwords do not match!",
})
}
password, _ := bcrypt.GenerateFromPassword([]byte(data["password"]), 14)
user := models.User{
FirstName: data["first_name"],
LastName: data["last_name"],
Email: data["email"],
Password: password,
}
return c.JSON(user)
}
Temos que trocar o campo Password de string para []byte no modelo user.
fiber-project/models/user.go
package models
type User struct {
Id uint
FirstName string
LastName string
Email string `gorm:"unique"`
Password []byte
}
Nesse ponto podemos fazer um teste com o postman, no endpoint http://localhost:8000/api/register
Saída:
{
“Id”: 0,
“FirstName”: “a”,
“LastName”: “a”,
“Email”: “a@mail.com”,
“Password”: “JDJhJDE0JC44TG9tVGRzb29GeGQxUWJpcW9MaWUuZFJiWThFaFo0V2lMOWdWQjAzL1NmSTJuc2s2aFJ5”
}
E fazer uma request POST e vê se a saída mostra a senha depois de passar pela função hash.
Agora vamos salvar a senha no banco.
Para isso, vamos precisar do fiber-project/database/connect.go dentro do fiber-project/controllers/authController.go.
Para fazer isso, vamos criar uma variável chamada DB, e ela será um ponteiro para o *gorm.DB que é o drive para acesso ao banco
A variável connection ela abre a conexão com o mysql, e o drive que tá referenciado pela variável DB, vai apontar para a connection.
fiber-project/database/connect.go
package database
import (
"fmt"
"fiber-project/models"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func Connect() {
var dsn = "toticavalcanti:mysql1234@/fluent_admin?charset=utf8mb4&parseTime=True&loc=Local"
var v = "Não conseguiu conectar ao banco de dados"
connection, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(v)
}
DB = connection
connection.AutoMigrate(&models.User{})
fmt.Println("Conexão OK!")
}
Ponteiros
Exemplo de uso de ponteiro
Agora podemos salvar o usuário e sua senha depois de passar pela função de hash.
fiber-project/controllers/authController.go
package controllers
import (
"fiber-project/database"
"fiber-project/models"
"github.com/gofiber/fiber/v2"
"golang.org/x/crypto/bcrypt"
)
func Register(c *fiber.Ctx) error {
var data map[string]string
if err := c.BodyParser(&data); err != nil {
return err
}
if data["password"] != data["confirm_password"] {
c.Status(400)
return c.JSON(fiber.Map{
"message": "Passwords do not match!",
})
}
password, _ := bcrypt.GenerateFromPassword([]byte(data["password"]), 14)
user := models.User{
FirstName: data["first_name"],
LastName: data["last_name"],
Email: data["email"],
Password: password,
}
database.DB.Create(&user)
return c.JSON(user)
}
Teste novamente usando o Postman.
{
“Id”: 1,
“FirstName”: “a”,
“LastName”: “a”,
“Email”: “a@mail.com”,
“Password”: “JDJhJDE0JC44TG9tVGRzb29GeGQxUWJpcW9MaWUuZFJiWThFaFo0V2lMOWdWQjAzL1NmSTJuc2s2aFJ5”
}