Gopress, un blog en Golang (parte 8)

Author picture
Published on 2023-05-14 07:04:16.735675087 +0200 +0200
Created by gerardooscarjt
one two
Views 606
Gopress, un blog en Golang (parte 8)

¡Hola a todos! Continuamos con nuestra serie sobre cómo construir un blog usando Golang, el lenguaje de programación creado por Google que se está volviendo cada vez más popular. Si te perdiste las partes anteriores, te invito a que vayas a nuestros artículos anteriores y te pongas al día. Hoy, en la octava entrega de nuestra serie, vamos a centrarnos en la autenticación y la seguridad. ¡Empecemos!

Checkboxes

Uno
Dos
Tres

Autenticación y seguridad

Hasta ahora, hemos creado nuestro blog, Gopress, con funcionalidades básicas, pero aún no hemos implementado ningún mecanismo de autenticación. No queremos que cualquier persona pueda publicar, editar o eliminar contenido en nuestro blog. Para prevenir eso, necesitamos implementar un sistema de autenticación.

En Golang, hay varias bibliotecas disponibles para ayudarnos con la autenticación, pero para este tutorial, utilizaremos "gorilla/sessions" para manejar las sesiones de usuario y "golang.org/x/crypto/bcrypt" para el hashing de contraseñas.

Implementando Sesiones con Gorilla/Sessions

Para comenzar, necesitamos instalar el paquete Gorilla Sessions. Si estás utilizando go modules, puedes hacerlo con el siguiente comando: 

bashCopy codego get github.com/gorilla/sessions

Primero, vamos a definir una variable global para nuestro almacenamiento de sesiones:

goCopy codevar ( key = []byte("super-secret-key") store = sessions.NewCookieStore(key) )

Una vez hecho esto, podemos implementar una función para establecer una sesión después de un inicio de sesión exitoso:

goCopy codefunc setSession(userName string, w http.ResponseWriter, r *http.Request) { session, _ := store.Get(r, "cookie-name") session.Values["authenticated"] = true session.Values["username"] = userName session.Save(r, w) }

Y otra función para verificar si un usuario está autenticado:

goCopy codefunc checkSession(r *http.Request) bool { session, _ := store.Get(r, "cookie-name") if auth, ok := session.Values["authenticated"].(bool); !ok || !auth { return false } return true }

Hashing de contraseñas con bcrypt

Ahora, vamos a manejar las contraseñas de manera segura con bcrypt. Puedes obtener bcrypt con el siguiente comando:

bashCopy codego get golang.org/x/crypto/bcrypt

Cuando un usuario se registra o cambia su contraseña, debemos asegurarnos de no almacenar la contraseña en texto plano. En su lugar, almacenaremos un hash de la contraseña. Aquí está la función para generar el hash de la contraseña:

goCopy codefunc hashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) return string(bytes), err }

Y cuando un usuario inicia sesión, podemos verificar la contraseña ingresada con el hash almacenado:

goCopy codefunc checkPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil }

¡Y eso es todo por hoy! Ahora tienes las herramientas para implementar la autenticación en tu blog Gopress. En la próxima entrada, nos centraremos en el manejo de roles y permisos para los usuarios. Como siempre, si tienes alguna pregunta o problema, no dudes en dejarnos un comentario.

Manejo de roles y permisos

Ahora que tenemos autenticación, podríamos querer implementar roles y permisos. Por ejemplo, tal vez queramos un rol de "editor" que pueda revisar y aprobar publicaciones antes de que se publiquen, y un rol de "autor" que pueda escribir y editar sus propias publicaciones, pero no las de otros.

Para implementar esto, primero debemos extender nuestro modelo de usuario para incluir un campo de rol:

goCopy codetype User struct { ID int Username string Password string Role string }

Luego, podemos verificar el rol de un usuario durante la autenticación. Aquí está una función de ejemplo que verifica si un usuario es un editor:

goCopy codefunc checkRole(r *http.Request) string { session, _ := store.Get(r, "cookie-name") role := session.Values["role"].(string) return role }

Podemos usar esta función en nuestros controladores para restringir el acceso a ciertas funciones basadas en el rol del usuario. Por ejemplo:

goCopy codefunc editPostHandler(w http.ResponseWriter, r *http.Request) { if !checkSession(r) { http.Redirect(w, r, "/login", 302) return } if checkRole(r) != "editor" { http.Error(w, "Forbidden", http.StatusForbidden) return } // ... código para editar la publicación ... }

En este código, redirigimos a los usuarios no autenticados a la página de inicio de sesión. Si el usuario está autenticado pero no es un editor, devolvemos un error 403 Forbidden. Solo los editores pueden acceder a la funcionalidad de edición de publicaciones.

Esperamos que este artículo te haya sido útil para entender cómo implementar autenticación y roles en tu blog Gopress. En la próxima entrada, exploraremos cómo implementar una funcionalidad de búsqueda en el blog. ¡Nos vemos en la próxima entrega!