CursosEmpresasBlogLiveConfPrecios

Implementando el middleware

Clase 16 de 26 • Curso de Go Avanzado: REST y WebSockets

Clase anteriorSiguiente clase

Contenido del curso

Introducción
  • 1
    Introducción al curso

    Introducción al curso

    02:27
  • 2
    ¿Qué estaremos construyendo?

    ¿Qué estaremos construyendo?

    04:51
  • 3
    HTTP y REST

    HTTP y REST

    06:34
  • 4
    CRUD

    CRUD

    05:58
REST
  • 5
    Inicialización de módulo e instalación de dependencias

    Inicialización de módulo e instalación de dependencias

    02:43
  • 6
    Struct Server

    Struct Server

    12:02
  • 7
    Nuestro primer endpoint

    Nuestro primer endpoint

    17:34
  • 8
    Definiendo el modelo de usuarios

    Definiendo el modelo de usuarios

    03:03
  • 9
    Patrón repository

    Patrón repository

    08:39
  • 10
    Registro de usuarios

    Registro de usuarios

    17:05
  • 11
    Implementando el registro

    Implementando el registro

    20:32
  • 12
    Probando los registros

    Probando los registros

    09:29
  • 13
    Autenticación de usuarios

    Autenticación de usuarios

    20:51
  • 14
    Probando el login

    Probando el login

    05:04
  • 15
    Middleware de validación de autenticación

    Middleware de validación de autenticación

    11:45
  • 16
    Implementando el middleware

    Implementando el middleware

    10:19
  • 17
    Modelo Posts

    Modelo Posts

    17:41
  • 18
    CRUD para Posts

    CRUD para Posts

    19:46
  • 19
    Paginación para Posts

    Paginación para Posts

    13:35
WebSockets
  • 20
    Websockets

    Websockets

    06:40
  • 21
    Upgrader y Endpoint para Websocket

    Upgrader y Endpoint para Websocket

    11:23
  • 22
    Struct de Hub para conexiones

    Struct de Hub para conexiones

    07:55
  • 23
    Implementando el Broadcast

    Implementando el Broadcast

    11:10
Cierre
  • 24
    Ejemplo de implementación frontend

    Ejemplo de implementación frontend

    14:54
  • 25
    Docker file para producción

    Docker file para producción

    11:44
  • 26
    Siguientes pasos y mejoras

    Siguientes pasos y mejoras

    01:39
    Christian Gonzalo Espinoza Cadillo

    Christian Gonzalo Espinoza Cadillo

    student•
    hace 3 años

    La solución que hace casi al final de la clase, la de modificar el fichero auth.go y enviar una referencia al models.AppClaims, también debe hacerse a la función de MeHandler

    func MeHandler(s server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { tokenString := strings.TrimSpace(r.Header.Get("Authorization")) token, err := jwt.ParseWithClaims(tokenString, &models.AppClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(s.Config().JWTSecret), nil }) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } if claims, ok := token.Claims.(*models.AppClaims); ok && token.Valid { user, err := repository.GetUserById(r.Context(), claims.UserId) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } else { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }
      Jonathan Stiven Colorado Largo

      Jonathan Stiven Colorado Largo

      student•
      hace 2 años

      Gracias me ayudo ese recordatorio

      NELSON ARLEY USUGA MONCADA

      NELSON ARLEY USUGA MONCADA

      student•
      hace 2 años

      👍

    Carlos Nexans

    Carlos Nexans

    student•
    hace 4 años

    La interface de la librería debería contemplar este problema en forma de chequeo de tipos y, especificar, que se debe recibir una referencia estrictamente. De esta forma el compilador te avisaría sobre este error en lugar de recibirlo cuando pruebas la aplicación.

      Victor Baruch Pazaran Jaimes

      Victor Baruch Pazaran Jaimes

      student•
      hace 3 años

      Exacto, si no lo hubiera notado el profesor estaría dificil de debuggear ese error, por que a simple vista no se sabe bien donde se está originando

    Àlex Grau Roca

    Àlex Grau Roca

    student•
    hace 3 años

    Para la abstracción de código he creado una carpeta llamada helpers y en ella un fichero llamado jwtHelper.go, el cual contiene la siguiente función:

    func GetJWTAuthorizationInfo(s server.Server, w http.ResponseWriter, r *http.Request) (*jwt.Token, error) { tokenString := strings.TrimSpace(r.Header.Get("Authorization")) token, err := jwt.ParseWithClaims(tokenString, models.AppClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(s.Config().JWTSecret), nil }) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) } return token, err }

    Los códigos que realizan la llamada la pueden utilizar tal que así:

    token, err := helpers.GetJWTAuthorizationInfo(s, w, r) if err != nil { return }
      Àlex Grau Roca

      Àlex Grau Roca

      student•
      hace 3 años

      Le falta añadir la referencia de models.AppClaims{}

    Edwin García

    Edwin García

    student•
    hace 3 años

    Ya para no duplicar el código del middleware de autorización lo que hice fue extraer ahí mismo el userId del token e insertarlo en los headers. Entonces cuando llega al MeHandler puedo extraer del los headers el userId. No se si esté bien, me gustaría que alguien me diera su opinión Este es el middleware

    middleware.png
    Este es el handler
    handler.png

      Matias Niz

      Matias Niz

      student•
      hace 3 años

      No se si es la respuesta correcta, pero tambien podes usar el context.

      en la funcion CheckAuthMiddleware:

      if claims, ok := token.Claims.(*models.AppClaims); ok && token.Valid { ctx := r.WithContext(context.WithValue(r.Context(), "userId", claims.UserId)) next.ServeHTTP(w, ctx) return }

      en MeHandler:

      result, ok := r.Context().Value("userId").(string) if ok { println(result) }
    Heiner Ríos Rodríguez

    Heiner Ríos Rodríguez

    student•
    hace 3 años

    Les comparto una opción para no repetir el código de verificación del token . En el middleware, al verificar el token podemos obtener el UserId y lo guardamos en el contexto de ejecución; posteriormente en el handler podemos recuperarlo y traer la data del usuario.


    middleware/auth.go

    func CheckAuthMiddleware(s server.Server) func(h http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !shouldCheckToken(r.URL.Host) { next.ServeHTTP(w, r) return } tokenString := strings.TrimSpace(r.Header.Get("Authorization")) token, err := jwt.ParseWithClaims(tokenString, &models.AppClaims{}, func(t *jwt.Token) (interface{}, error) { return []byte(s.Config().JWTSecret), nil }) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } claims, ok := token.Claims.(*models.AppClaims) if ok && token.Valid { log.Printf("User ID: %s", claims.UserId) ctx := context.WithValue(r.Context(), ContextUserID, claims.UserId) r = r.WithContext(ctx) }// next.ServeHTTP(w, r) }) } }

    handlers/user.go

    func MeHandler(s server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID := r.Context().Value(middleware.ContextUserID) if userID == "" { http.Error(w, "Invalid credentials", http.StatusUnauthorized) return } user, err := repository.GetUserById(r.Context(), userID.(string)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } }
      Heiner Ríos Rodríguez

      Heiner Ríos Rodríguez

      student•
      hace 3 años

      El ContextUserID lo pueden definir así:

      type ContextKey string const ContextUserID ContextKey = "userid"
    Carlos Eduardo Magallon Zepeda

    Carlos Eduardo Magallon Zepeda

    student•
    hace 4 años
    func MeHandler(s server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { tokenString := strings.TrimSpace(r.Header.Get("Authorization")) token, err := jwt.ParseWithClaims(tokenString, &models.AppClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(s.Config().JWTSecret), nil }) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } if claims, ok := token.Claims.(*models.AppClaims); ok && token.Valid { user, err := repository.GetUserById(r.Context(), claims.UserId) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } else { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }
    Luis Alfredo Hernández Duarte

    Luis Alfredo Hernández Duarte

    student•
    hace 3 años

    Cómo hago para enviar un Bearer token en vez del token solo?

    Oscar Gómez Rodríguez

    Oscar Gómez Rodríguez

    student•
    hace un año

    En esta clase tenemos un problema ya que creamos el mdw pero replicamos todo el código dentro del un nuevo handler, lo unico que debimos hacer fue agregar en los routes este mdw de la siguiente forma:

    func BindRoutes(s server.Server, r *mux.Router) { r.HandleFunc("/", handlers.HomeHandler(s)).Methods("GET") r.HandleFunc("/signup", handlers.SingUpHandler(s)).Methods("POST") r.HandleFunc("/login", handlers.LoginHandler(s)).Methods("POST") r.HandleFunc("/me", handlers.MeHandler(s)).Methods("GET") r.Use(middleware.CheckAuthMiddleware(s)) } ```func BindRoutes(s server.Server, r \*mux.Router) { r.HandleFunc("/", handlers.HomeHandler(s)).Methods("GET") r.HandleFunc("/signup", handlers.SingUpHandler(s)).Methods("POST") r.HandleFunc("/login", handlers.LoginHandler(s)).Methods("POST") r.HandleFunc("/me", handlers.MeHandler(s)).Methods("GET") r.Use(middleware.CheckAuthMiddleware(s))}
    Carlos Arturo Pimentel

    Carlos Arturo Pimentel

    student•
    hace 3 años

    Una posible solución para el reto que nos plantea Nestor es la siguiente:

    func ParseToken(hauth string, claims jwt.Claims) (jwt.Token, error) { // hauth: Autohorization Header // claims: Any type that implemnts jwt.Claims. AppClaims Does b/c jwt.StandardClaims does. strim := strings.TrimSpace(hauth) token, err := jwt.ParseWithClaims(strim, claims, func(t *jwt.Token) (interface{}, error) { return []byte(database.BuildConfig().JWTSecret), nil }) return *token, err }

    el database.BuildConfig está apuntando al archivo de configuración,, que a propósito no estaría mal sacarlo de server.go y tenerlo en su propio archivo config.go., esto entre otras cosas ahorraría tener que pasar el servidor como parámetro en los los middlewares.

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads