{"id":1193,"date":"2022-11-16T04:04:56","date_gmt":"2022-11-16T04:04:56","guid":{"rendered":"https:\/\/blog.thepragmatic.xyz\/?p=1193"},"modified":"2023-03-12T22:34:31","modified_gmt":"2023-03-12T22:34:31","slug":"json-web-tokens","status":"publish","type":"post","link":"https:\/\/blog.thepragmatic.xyz\/?p=1193","title":{"rendered":"JSON Web Token based authentication"},"content":{"rendered":"\n<h2>Intro Diego<\/h2>\n\n\n\n<p><strong>Cookies<\/strong> (Viejas) de lado cliente se puede ver la info en el header (forma insegura guardar informacion, cambiar informacion del lado del servidor) (Preferencias, anuncios) STATEFUL (seguimiento del estado de la informaci\u00f3n) Almacenar preferencias del idioma, configuraciones (custom para no iniciar desde 0)<\/p>\n\n\n\n<p><strong>tradicional <\/strong>(Basado en sessi\u00f3n) guardar informacion a trav\u00e9s del servidor, pero utilizando cookies. SESIONES: toda la informacion se guarda del lado del servidor, mientras se tiene la sesi\u00f3n abierta.<\/p>\n\n\n\n<p>traer la informacion del usuario a trav\u00e9s de una cookie, ya no se guarda toda la informaci\u00f3n, sino un ID o un registro que le permite al servidor identificar a que usuario pertenece ese ID (PHPSESSID=3c7f0j34). Las sesiones conviven tanto del lado del servidor como del cliente, en el cliente solo se tiene un ID que se guarday cada que se haga una request HTTP, el navegador va a tomar esa cookie si existe y la envia de vuelta al servidor. En el servidor se valida el id o el registro que tiene almacenado y con eso se identifica la informacion asociada a ese id. M\u00e9todo un poco mas seguro, no se guarda toda la info de lado del cliente (exposicion data sensible), ahora la informacion esta del lado del servidor. No es totalmente segura pero garantiza un nivel mayor de proteccion sw la informacion.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Historia<\/h2>\n\n\n\n<p>El proceso de autenticaci\u00f3n ha evolucionado bastante los \u00faltimos a\u00f1os debido a la revoluci\u00f3n m\u00f3vil, la arquitectura de aplicaciones basadas en microservicios, cloud computing e IoT. Las conexiones ya no se establecen con servicios internos de las compa\u00f1ias exclusivamente, todos o la mayor\u00eda de nuestros dispositivos se conectan a internet o redes p\u00fablicas que dejan fuera los controles de seguridad que se dispon\u00edan en las redes privadas<strong>.<\/strong> Surgieron algunos retos, la gran cantidad de clientes, dificultad para escalar y finalmente el manejo de sesi\u00f3n; Para solucionar esta necesidad aparecieron  3 tecnolog\u00edas: JSON Web Tokens, OAuth 2.0, OpenID Connect. Qu\u00e9 actualmente son consideradas como el <em><strong>stack de seguridad para aplicaciones modernas<\/strong><\/em>. En este art\u00edculo se tratar\u00e1 la <strong>autenticaci\u00f3n basada en JSON Web Tokens<\/strong>, cabe aclarar que el concepto de token se introduj\u00f3 en las aplicaciones web por la autenticaci\u00f3n y autorizaci\u00f3n moderna y su uso se extiende gracias al protocolo Oauth (actualmente OAuth 2.0), centrados en la autorizaci\u00f3n y no en la autenticaci\u00f3n como se tienden a confundir. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">PULIR<\/mark><\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>\u00ab<em>La principal diferencia entre OAuth y OpenID Connect es que OAuth se centra en la autorizaci\u00f3n, mientras que OpenID Connect se centra en la autenticaci\u00f3n. OAuth se utiliza para permitir que las aplicaciones de terceros accedan a los recursos protegidos de un usuario en un servicio en l\u00ednea, mientras que OpenID Connect se utiliza para autenticar a los usuarios en aplicaciones web y m\u00f3viles.\u00bb<br><br>OAuth se centra en la autorizaci\u00f3n, y no en la autenticaci\u00f3n, es decir, permite que una aplicaci\u00f3n acceda a los recursos de un usuario sin revelar su contrase\u00f1a o credenciales de autenticaci\u00f3n al tercero.<\/em><\/p><p><em>OIDC utiliza los mecanismos de autorizaci\u00f3n de OAuth 2.0 y agrega una capa de autenticaci\u00f3n en la parte superior. OIDC permite a los usuarios autenticarse con una identidad digital (por ejemplo, una cuenta de Google) y recibir un token de acceso para acceder a los recursos protegidos en una aplicaci\u00f3n de terceros.<\/em><\/p><cite>random<\/cite><\/blockquote>\n\n\n\n<p>Ahora es pertinente aclarar los tipos de autenticaci\u00f3n con tokens: <\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Autenticaci\u00f3n tradicional o autenticaci\u00f3n en servidor<\/strong><\/td><td><strong>Autenticaci\u00f3n sin estado basada en tokens<\/strong><\/td><\/tr><tr><td>Fue el modo de autenticaci\u00f3n m\u00e1s habitual. Al usuario autenticarse el servidor le devuelve al cliente un token que es almacenado en una cookie. El servidor guarda la informaci\u00f3n de la sesi\u00f3n en memoria o en base de datos. Al solicitar un recurso con ese token, el servidor realiza la b\u00fasqueda para identificar quien intenta acceder y si es v\u00e1lida, ejecuta la solicitud. Puede presentar sobrecargas (cantidad de usuarios) y problemas de escalabilidad (replicar la sesi\u00f3n en varias instancias). Vulnerabilidades asociadas a la arquitectura (CORS, CSRF).<br>Intercambio de recursos de origen cruzado<br>falsificaci\u00f3n de petici\u00f3n en sitios cruzados)<\/td><td>Stateless significa que el servidor no almacena ninguna informaci\u00f3n, ni tampoco la sesi\u00f3n. Al usuario autenticarse, recibe un token (<strong>access token<\/strong>) en la respuesta. Desde ah\u00ed todas las peticiones hacia la API llevar\u00e1n este token (HTTP header), as\u00ed el servidor podr\u00e1 identificar al usuario que hace la petici\u00f3n sin necesidad de hacer consultas. Se proporciona escalabilidad, las peticiones podr\u00edan ser atendidas por cualquier instancia del servidor sin requerir sincronizaci\u00f3n ya que el cliente almacena su informaci\u00f3n de autenticaci\u00f3n y no el servidor. Diferentes plataformas podr\u00e1n usar la misma API.<br>Al no existir sesiones (RESTFul) se evitan vulnerabilidades CSRF. La expiraci\u00f3n del token provee una mayor seguridad.<br><\/td><\/tr><\/tbody><\/table><figcaption>Comparativo autenticaci\u00f3n tradicional vs Basada en tokens.<\/figcaption><\/figure>\n\n\n\n<h2>\u00bfQu\u00e9 son JSON Web Tokens?<\/h2>\n\n\n\n<p>Seg\u00fan la RFC 7519:<\/p>\n\n\n\n<p><em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\">JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and\/or encrypted.<\/mark><\/em><\/p>\n\n\n\n<p>B\u00e1sicamente es un est\u00e1ndar abierto de intercambio de datos entre 2 partes (sistemas) basado en JSON, que permite crear tokens de acceso, actualmente est\u00e1 bien aceptado pero hay mas alternativas. Se puede encontrar en est\u00e1ndares populares, como OpenID Connect u OAuth 2.0. Es ampliamente utilizado en empresas de diversas escalas, existen variedad de bibliotecas compatibles con JWT, cuenta con gran soporte. Propone que no haya un estado en el servidor de autenticaci\u00f3n, por ende coincide bastante  con las API RESTFul. Se utilizan tokens firmados con las credenciales de autenticaci\u00f3n de los usuarios en vez de guardar estos estados con cookies en los servidores, como lo hace la autenticaci\u00f3n basada en sesi\u00f3n.<\/p>\n\n\n\n<p>As\u00ed se ve un JSON Web Token:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/research.securitum.com\/wp-content\/uploads\/sites\/2\/2019\/10\/jwt_ng1_en.png\" alt=\"\"\/><figcaption><em>Imagen n: Estructura de un JSON Web Token [Redise\u00f1ar imagen]<\/em><\/figcaption><\/figure>\n\n\n\n<p>Visto de otra forma JWT es una secuencia de caracteres en formato JSON codificados en la estructura <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">JWS (JSON Web Signature) o JWE (JSON Web Encryption). Esencialmente sirven para representar unos claims (permisos, requerimientos, privilegios) entre 2 partes. A su vez suele ser un simple par de \u201cclave\u201d: \u201cvalor\u201d.<\/mark>   CORROBORAR.  PODRIA CABER UN PARA QUE SIRVEN?<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>\u00bfC\u00f3mo funciona un sistema de autenticaci\u00f3n basado en JWT?<\/h2>\n\n\n\n<p>Simplemente una de las partes genera y entrega un token con la identificaci\u00f3n y los permisos de cada usuario. Este token es almacenado por la otra parte es decir el cliente, y enviado cada que requiera utilizar o consumir cierto recurso. As\u00ed que siempre que las aplicaciones necesitan verificar los permisos de los usuarios, simplemente deben validar los tokens. Se conf\u00eda en que el JSON Web Token es el mecanismo que le concede esos permisos o autorizaciones. Gracias a este tipo de autenticaci\u00f3n se descarta el uso de un servicio de backend para almacenar las sesiones de autenticaci\u00f3n de los usuarios, solo con guardar y validar los tokens se pueden controlar los permisos para cada usuario.<\/p>\n\n\n\n<p>En esencia son 3 cadenas de texto, separadas por un punto, la primera cadena corresponde al header, hay que aclarar que esto no est\u00e1 cifrado est\u00e1 codificado, quiere decir que se puede decodificar es reversible. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Dilema del manejo de sesi\u00f3n \u00abNo uses JWT para gestionar sesiones\u00bb (Detractores)<\/h2>\n\n\n\n<p>Muchas personas intentan comparar \u201ccookies vs JWT\u201d. Esta comparaci\u00f3n no tiene sentido, y es comparar manzanas con naranjas -las cookies son un mecanismo de almacenamiento, mientras que las JWT tokens son tokens firmadas criptogr\u00e1ficamente. <strong>No son opuestos<\/strong> &#8211; sino que pueden ser usadas ya sea de manera conjunta o independiente. La comparaci\u00f3n correcta es \u201c<strong>sesiones vs JWT<\/strong>\u201d y \u201ccookies vs Local Storage\u201d. Los JWT no son adecuados como un mecanismo de sesiones.<\/p>\n\n\n\n<p>Los casos de uso donde las JWT son particularmente efectivas son t\u00edpicamente los casos de uso donde son usadas como un token de autorizaci\u00f3n de \u00fanico uso. Pero como todo en la vida y en la ingenieria \u00abdepende\u00bb. Hay una fuerte discusi\u00f3n en torno a este dilema, no es el objetivo de esta exposici\u00f3n, pero les dejo la inquietud, por si alguien esta interesado en ahondar.<\/p>\n\n\n\n<h2>Ventajas y Desventajas<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Ventajas<\/td><td class=\"has-text-align-center\" data-align=\"center\">Desventajas<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">F\u00e1cil implementaci\u00f3n y posibilidad de customizaci\u00f3n.<\/td><td class=\"has-text-align-center\" data-align=\"center\">Alto riesgo en caso de que el secret sea comprometido. De ser as\u00ed la \u00fanica soluci\u00f3n es generar uno nuevo, lo que implica nuevo login para todos.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Puede ser firmado mediante una clave p\u00fablica y privada, o utilizando un secret (HMAC).<\/td><td class=\"has-text-align-center\" data-align=\"center\">F\u00e1cil de implementar, dif\u00edcil de comprender debido a los algoritmos que se utilizan para firmar el token.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Portable, un mismo token puede utilizarse en m\u00faltiples backends.<\/td><td class=\"has-text-align-center\" data-align=\"center\">Data overhead, a mayor informaci\u00f3n que agreguemos en el body, mayor el tama\u00f1o del request.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">No hay manejo de sesi\u00f3n ni cookies (stateless). Utilizado por Single Page Applications (IoT)<\/td><td class=\"has-text-align-center\" data-align=\"center\">No hay forma de bloquear un token en tiempo real,. S\u00ed se puede bloquear un refresh token<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Buena performance, luego de la autenticaci\u00f3n no necesita de recursos externos para validar el token.<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><\/tr><\/tbody><\/table><figcaption>Tabla: Ventajas y Desventajas<\/figcaption><\/figure>\n\n\n\n<h2>Tipos de token<\/h2>\n\n\n\n<p>Existen muchos tipos de token, lo mas comunes son el access token y el refresh token.<\/p>\n\n\n\n<ul><li><strong>Access token:<\/strong> Contiene la informaci\u00f3n que necesita el servidor para determinar si un usuario puede acceder o no al recurso que  solicita. Con frecuencia su tiempo de expiraci\u00f3n es  corto.<\/li><li><strong>Refresh token:<\/strong> Se utiliza para generar un nuevo access token. Normalmente, al caducar un access token (con fecha de expiraci\u00f3n), el usuario deber\u00eda autenticarse con el fin de generar uno nuevo. Utilizando un refresh token, se puede evitar este paso, y a trav\u00e9s de una petici\u00f3n a la API obtener un access token nuevo para continuar accediendo a los recursos de la aplicaci\u00f3n. Tal vez sea necesario generar un access token si se desea acceder a un recurso  que no fue accedido previamente, esto depende de las restricciones en la implementaci\u00f3n de la API.  El refresh token requiere una mayor seguridad al momento de ser almacenado con respecto al access token, dado que en caso de ser sustra\u00eddo, puede ser utilizado por terceros para obtener access tokens y acceder a recursos protegidos de la aplicaci\u00f3n. Para controlar este riesgo, se debe implementar en el servidor alg\u00fan mecanismo que permita invalidar un refresh token. En la pr\u00e1ctica, en la respuesta a la autenticaci\u00f3n se retorna tanto el token JWT como el refresh token con el que se podr\u00e1 solicitar nuevos tokens de acceso.<\/li><\/ul>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Quiza pueda caber el bearer&#8230; y los otros..<\/mark><\/p>\n\n\n\n<h2>Estructura de un JWT<\/h2>\n\n\n\n<p><strong>Header:<\/strong> Contiene el algoritmo utilizado para firmar (\u00abalg\u00bb: \u00abHS512\u00bb) y el tipo de token \u00abtyp\u00bb: \u00abJWT\u00bb. Existen varios tipos de token pero el m\u00e1s com\u00fan es el JWT.<\/p>\n\n\n\n<p>{<br>\u00abalg\u00bb: \u00abHS512\u00bb,<br>\u00abtyp\u00bb: \u00abJWT\u00bb<br>}<\/p>\n\n\n\n<p><strong>Payload(Cuerpo):<\/strong>  Es la informaci\u00f3n que contiene el token como tal, por ejemplo: \u00bfPara qui\u00e9n es el token? El issuer o quien emite el token, el usuario asociado al token, \u00bfCuando fue creado el token?, expiraci\u00f3n del token,  normalmente llevan un identificador.  Estas propiedades son conocidas como Claims.<\/p>\n\n\n\n<h3>Tipos de Claims<\/h3>\n\n\n\n<h4>Registered Claim Names (Registrados) <\/h4>\n\n\n\n<p>Tambi\u00e9n se les conoce como standard claims, son los principales definidos en el est\u00e1ndar, generalmente no se deber\u00edan sobreescribir. Los Claims deben ser muy cortos porque se espera que el JWT no sea muy pesado, se intenta utilizar m\u00e1ximo 3 letras.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Claim<\/td><td class=\"has-text-align-center\" data-align=\"center\">Descripci\u00f3n<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Issuer \u00abiss\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Qui\u00e9n gener\u00f3 el JWT (Proveedor de identidad).<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Subject \u00absub\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Identificaci\u00f3n del usuario. Normalmente es un Id de usuario el que es asignado ac\u00e1.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Audience \u00abaud\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Para qui\u00e9n va a este token. Puede tener multiples audiencias, Normalmente un token puede servir para acceder a varios servicios.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Expiration Time \u00abexp\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Fecha de expiraci\u00f3n.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Not Before \u00abnbf\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Tiempo cuando el JWT comienza a ser valido.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Issued At \u00abiat\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Momento en que el JWT fue emitido<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">JWT ID \u00abjti\u00bb<\/td><td class=\"has-text-align-center\" data-align=\"center\">Identificador \u00fanico para el JWT.<\/td><\/tr><\/tbody><\/table><figcaption>Estandar Claims<\/figcaption><\/figure>\n\n\n\n<p><em>Not<strong>a:<\/strong> No es obligatorio utilizar o implementar todos los StandardClaims, simplemente proporcionan un punto de partida.<\/em><\/p>\n\n\n\n<h4>Public Claim Names<\/h4>\n\n\n\n<p>Como los anteriores, tampoco se deber\u00edan de sobreescribir, es decir asignar un significado diferente. Para evitar colisiones, cualquier Claim nuevo debe ser registrado ante el registro IANA. <a href=\"https:\/\/www.iana.org\/assignments\/jwt\/jwt.xhtml\">https:\/\/www.iana.org\/assignments\/jwt\/jwt.xhtml<\/a><\/p>\n\n\n\n<p>Ejemplo: <\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Claim Name<\/td><td>Claim Description<\/td><\/tr><tr><td>name<\/td><td>Full name<\/td><\/tr><tr><td>family_name<\/td><td>Surnames(s) or last name(s)<\/td><\/tr><tr><td>email<\/td><td>Preferred e-mail address<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4>Private Claim Names<\/h4>\n\n\n\n<p>Los claims privados est\u00e1n sujetos a colisi\u00f3n y deben utilizarse con precauci\u00f3n. Son definidos de acuerdo a la necesidad del desarrollador. Ej: Quiz\u00e1s se necesite un rol para determinar si es administrador, invitado o similares. <\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><em>Nota: En el payload no debe haber informaci\u00f3n sensible<\/em>, debido a que esto puede ser decodificado, cualquiera puede leer el contenido del header o payload del JWT. <\/p><\/blockquote>\n\n\n\n<h3>Signature<\/h3>\n\n\n\n<p>Servir\u00e1 para verificar que el token no ha sido cambiado, y que es v\u00e1lido. Todos los tokens JWT se firman. utilizando criptograf\u00eda sim\u00e9trica (Secreto) que no es lo m\u00e1s recomendado, y as\u00edm\u00e9trica.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>HS256, se recomienda en este tipo de firma utilizar un string de 256 bits. <\/p>\n\n\n\n<h3>\u00bfQu\u00e9 tan seguros son los JSON Web Tokens?<\/h3>\n\n\n\n<p>Ac\u00e1 es donde toma protagonismo la tercera cadena (Signature). Esta no puede ser verificada as\u00ed no m\u00e1s. Es una firma que ha sido cifrada usando el algoritmo especificado en el header. Recordar que seg\u00fan la criptograf\u00eda moderna, hay cifrados sim\u00e9tricos y asim\u00e9tricos. Utilizar un esquema de cifrado sim\u00e9trico implica que la llave privada es la misma que se usa para firmar, cifrar y descifrar, generalmente no suele ser tan seguro. (En este ejemplo se tiene <strong>HS256<\/strong> a modo de ejemplo). Se recomienda utilizar un algoritmo asim\u00e9trico. Donde se tiene una llave privada y una p\u00fablica, Ej. Autenticaci\u00f3n mediante SSH Keys. Si por alguna raz\u00f3n la llave privada cae en malas manos, entonces cualquiera podr\u00eda firmar nuestro JWT. <\/p>\n\n\n\n<h3>\u00bfC\u00f3mo funciona este mecanismo de seguridad mediante firma para JWT? (Hacerlo no vulnerable)<\/h3>\n\n\n\n<p>Ej: <strong>Agregar \u00abrole\u00bb: \u00abAdmin\u00bb<\/strong> en el Payload. Autom\u00e1ticamente se actualiza el JWT. Pero la firma siempre se compone de codificar en base 64 el header, concatenado con un punto [.], a su vez concatenado con el payload tambi\u00e9n codificado en base 64, y se firma utilizando un secreto.<\/p>\n\n\n\n<p><strong>Ejemplo con firma JWT<\/strong><\/p>\n\n\n\n<p>Esta es la llave secreta que no se deber\u00eda compartir con nadie, se recomienda en este tipo de firma utilizar un string de 256 bits. (Utilizar este sitio web para generar un string con esta caracter\u00edstica , <a href=\"https:\/\/keygen.io\/\" data-type=\"URL\" data-id=\"https:\/\/keygen.io\/\">https:\/\/keygen.io\/<\/a> puede ser SHA 256-bit Key o SHA 512-bit Key) <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\">[<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">a17dd50914c1bdd70a01c259b6dc23304697a25095ca67b8d99be242c614c14f<\/mark>]<\/p>\n\n\n\n<p>Se copia y se pega el string generado en el campo de texto del secreto y se <strong>genera una firma completamente diferente.<\/strong> <a href=\"https:\/\/jwt.io\/\">https:\/\/jwt.io\/<\/a><\/p>\n\n\n\n<p>Se va a tener una copia de esta version: VERSION FIRMADA<\/p>\n\n\n\n<p>[<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJyb2xlIjoiQWRtaW4ifQ.C-p0Lw68ipgznkQPaN-yBOW61jdvnw7pY_cGNEmi1AY<\/mark>]<\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>Signature Verified<\/strong><\/mark><\/p>\n\n\n\n<p>JWT tiene esta estructura Si alguien por casualidad, la \u00fanica forma de generar esta tercera cadena que es la firma es conociendo el secreto, y est\u00e1 compuesto del header y el payload. <\/p>\n\n\n\n<p>\u00abSi alguien quisiera vulnerar este JWT y cambiar el payload con informaci\u00f3n nueva, no podr\u00eda. Es necesario conocer la llave secreta para poder volverlo a firmar. <\/p>\n\n\n\n<p>Se va a suponer que se va a vulnerar este JWT.  En vez de admin se va a poner que va a ser superAdmin.<\/p>\n\n\n\n<p>Agregar \u00abrole\u00bb: \u00absuperadmin\u00bb<\/p>\n\n\n\n<p>Se evidencia que el header no va a cambiar. <\/p>\n\n\n\n<p>pero como solo puedo conocer esta firma. (Se coloca la firma anterior)<\/p>\n\n\n\n<p>Va a indicar que es invalido.<\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>Invalid Signature<\/strong><\/mark><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>De nuevo este payload es diferente, y cuando se va a verificar el JWT necesita el header que no ha cambiado, pero como el payload si ha cambiado con la firma, como resultado va a entregar una cadena completamente diferente. Este es el mecanismo que utilizan los JWT para saber si fueron vulnerados o no.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/auth0.com\/blog\/rs256-vs-hs256-whats-the-difference\/\">https:\/\/auth0.com\/blog\/rs256-vs-hs256-whats-the-difference\/<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Ciclo de vida de un token JWT<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" width=\"862\" height=\"340\" src=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-1.png\" alt=\"\" class=\"wp-image-1452\" srcset=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-1.png 862w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-1-300x118.png 300w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-1-768x303.png 768w\" sizes=\"(max-width: 862px) 100vw, 862px\" \/><figcaption>Imagen n: ciclo de vida de un token JWT [redise\u00f1ar]<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3>Procedimiento<\/h3>\n\n\n\n<ul><li>Decodificar lo que se esta enviando a trav\u00e9s del cliente,<\/li><li>Ir a traer ese usuario por el email<\/li><li>Verificar que las credenciales esten correctas, es decir que el usuario exista y que el password este bien hecho.<\/li><li>Empezar a generar ese token que se va a enviar como respuesta,<\/li><li>Responder con el token recien creado<\/li><\/ul>\n\n\n\n<h2>Demostraci\u00f3n\/Implementaci\u00f3n en Golang<\/h2>\n\n\n\n<h3>(JWT based authentication) dummy-auth-users-jwt<\/h3>\n\n\n\n<p>Usando autenticaci\u00f3n JWT en un servidor HTTP construido en Go<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/DiegoAll\/dummy-auth-users-jwt\">https:\/\/github.com\/DiegoAll\/dummy-auth-users-jwt<\/a>   <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Recordar decodificar el JWT generado por el server anterior en la p\u00e1gina (Debugger)<\/p>\n\n\n\n<p><a href=\"https:\/\/jwt.io\/\">https:\/\/jwt.io\/<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3>Extensiones navegador para validar SAML Analyzer &#8230; (ceron)<\/h3>\n\n\n\n<p>oelo<\/p>\n\n\n\n<h3>Partiendo de https:\/\/gowebexamples.com\/ <\/h3>\n\n\n\n<p><\/p>\n\n\n\n<h2>Seguridad\/Vulnerabilidad\/Riesgos en los JWT<\/h2>\n\n\n\n<p>Cross site request forgery : Mecanismo mediante el cual para realizar peticiones sobre todo POST, el cliente tiene que enviar un token <strong>(token CSRF)<\/strong> al servidor. Si este no valida dicho token, la operacion no se realiza.  (Bad request The CSRF session token is missing) o no es valido. Proteccion CSRF.<\/p>\n\n\n\n<p>Un sitio web podr\u00eda hacer peticiones maliciosas hacia otro sitio web seguro si, por ejemplo se tienen 2 pesta\u00f1as a la vez en el navegador. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Conclusiones<\/h2>\n\n\n\n<ul><li>JWT permite aumentar la eficiencia de nuestras aplicaciones evitando m\u00faltiples llamadas a la base de datos, y de este modo reducir la latencia. <\/li><li>A su vez con el uso de refresh tokens se mejora la seguridad y usabilidad de esta arquitectura.<\/li><li>El uso de tokens para la autenticaci\u00f3n es de gran utilidad para gran cantidad de proyectos, sin embargo no es el Santo Grial que soluciona todos los problemas, ni sirve para todos los productos. (Debe considerarse al plantear cualquier soluci\u00f3n)<\/li><\/ul>\n\n\n\n<ul><li>Es obvio pero el JWT no requiere cerrar sesi\u00f3n. (corroborar)<\/li><\/ul>\n\n\n\n<p>Protecci\u00f3n CSRF en mi API REST<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"PROTECCI\u00d3N CSRF EN MI API REST\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/N08q_zQlolo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/bcrypt.online\/\">https:\/\/bcrypt.online\/<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>In Deep (If Apply)<\/strong><\/p>\n\n\n\n<p>JWE <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Alternativas a JWT<\/h2>\n\n\n\n<p>Fernet<\/p>\n\n\n\n<p>Branca<\/p>\n\n\n\n<p>PASETO (Pasito)<\/p>\n\n\n\n<p><a href=\"https:\/\/www.scottbrady91.com\/jose\/alternatives-to-jwts\">https:\/\/www.scottbrady91.com\/jose\/alternatives-to-jwts<\/a><\/p>\n\n\n\n<h2><strong>Referencias<\/strong><\/h2>\n\n\n\n<p><a href=\"https:\/\/github.com\/golang-jwt\">https:\/\/github.com\/golang-jwt<\/a> Community maintained clone of https:\/\/github.com\/dgrijalva\/jwt-go<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/www.sohamkamani.com\/golang\/session-cookie-authentication\/\">https:\/\/www.sohamkamani.com\/golang\/session-cookie-authentication\/<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.sohamkamani.com\/golang\/jwt-authentication\/\">https:\/\/www.sohamkamani.com\/golang\/jwt-authentication\/<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/dwyl\/learn-json-web-tokens\">https:\/\/github.com\/dwyl\/learn-json-web-tokens<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/auth0.com\/blog\/refresh-tokens-what-are-they-and-when-to-use-them\/#xss-xsrf\">https:\/\/auth0.com\/blog\/refresh-tokens-what-are-they-and-when-to-use-them\/#xss-xsrf<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/JSON_Web_Token_for_Java_Cheat_Sheet.html\">https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/JSON_Web_Token_for_Java_Cheat_Sheet.html<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/auth0.com\/blog\/rs256-vs-hs256-whats-the-difference\/\">https:\/\/auth0.com\/blog\/rs256-vs-hs256-whats-the-difference\/<\/a><\/p>\n\n\n\n<p>\/\/ https:\/\/bravedeveloper.com\/2021\/09\/01\/que-es-rest-restful-api-restful-y-json\/<\/p>\n\n\n\n<p><a href=\"https:\/\/web-token.spomky-labs.com\/the-components\/signed-tokens-jws\/signature-algorithms\">https:\/\/web-token.spomky-labs.com\/the-components\/signed-tokens-jws\/signature-algorithms<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/coffeebytes.dev\/no-uses-jwt-para-gestionar-sesiones-traduccion\/\">https:\/\/coffeebytes.dev\/no-uses-jwt-para-gestionar-sesiones-traduccion\/<\/a><\/p>\n\n\n\n<p>http:\/\/cryto.net\/~joepie91\/blog\/2016\/06\/13\/stop-using-jwt-for-sessions\/ <\/p>\n\n\n\n<p>\/\/ https:\/\/ahorasomos.izertis.com\/solidgear\/refresh-token-autenticacion-jwt-implementacion-nodejs\/ * [refresh tokens]<\/p>\n\n\n\n<p><a href=\"https:\/\/www.scottbrady91.com\/jose\/alternatives-to-jwts\">https:\/\/www.scottbrady91.com\/jose\/alternatives-to-jwts<\/a> [Alternativas a JWT]<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2><strong>Plus Seguridad SW<\/strong><\/h2>\n\n\n\n<p>hash funcion de doble via .. (Reinaldo y apuntes creo que bcrypt tiende a ser deprecado)<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>bcrypt intentar cambiar a sha2. &#8230; ojala sha3<\/p>\n\n\n\n<p>hashedPassword, err := bcrypt.GenerateFromPassword([]byte(request.Password), bcrypt.DefaultCost)<\/p>\n\n\n\n<p>MaxCost, minCost<\/p>\n\n\n\n<p>DefaultCost (como variable de entorno o Config)<\/p>\n\n\n\n<p>ExpiresAt (como variable de entorno o Config)<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Background<\/h2>\n\n\n\n<h3>Autenticaci\u00f3n tradicional vs JWT<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" width=\"807\" height=\"461\" src=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-2.png\" alt=\"\" class=\"wp-image-1497\" srcset=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-2.png 807w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-2-300x171.png 300w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-2-768x439.png 768w\" sizes=\"(max-width: 807px) 100vw, 807px\" \/><\/figure>\n\n\n\n<p>clasica: Consiste en que un usuario se autentica ante una base de datos, debe existir, usuario y contrase\u00f1a, passwordless, correo huella etc. Si el usuario existe en la base de datos, est\u00e1 autenticado lo que hace el servidor es que crea una sesi\u00f3n, vease como un espacio en memoria. Esa sesi\u00f3n genera un id, tiene un id para identificar esa sesi\u00f3n especifica de este usuario. Lo que luego hace el servidor es que ese id de la sesi\u00f3n lo mete en una cookie. <\/p>\n\n\n\n<p>Las cookies se refieren a las galletas de la fortuna que tienen mensajes adentro, se ven representadas como galletas con chips de chocolate, realmente la manera correcta de hacerlo, como se emple\u00f3 es con las galletas de la fortuna, por que tienen mensajes ocultos. <\/p>\n\n\n\n<p>Entonces el servidor crea la cookie y adentro lo que almacena es el id de la sesi\u00f3n, es un identificador, no es nada secreto ni nada, simplemente es un id. Esa cookie que es creada es enviada al cliente, y el cliente la guarda como una cookie. Es algo que ya hace mucho tiempo soportan los navegadores. <\/p>\n\n\n\n<p>Simplemente lo que se hace es que cualquier request que se haga de ahi en adelante. Siempre se envia la cookie, de esa manera cuando el servidor recibe el request, verifica que el Id que est\u00e1 en la cookie, sea compatible con el de la sesi\u00f3n, es m\u00e1s que la sesi\u00f3n exista, porque la sesi\u00f3n puede ser destru\u00edda.<\/p>\n\n\n\n<p>Sino existe la sesi\u00f3n se acabo por ende el usuario no est\u00e1 autenticado.<\/p>\n\n\n\n<p>\u00bfCuales son los problemas con este approach?<\/p>\n\n\n\n<p>Los problemas empiezan a surgir remontandose a la autenticaci\u00f3n tradicional, y por que se di\u00f3 el cambio al stack de seguridad para aplicaciones modernas. Las Single Page App que son aplicaciones que viven en el cliente,  conocidas tambi\u00e9n como client side applications, no refrescan. (REVISAR INFO DE ARQUITECTURAS SERVER SIDE\/ CLIENT SIDE). <\/p>\n\n\n\n<p>Cuando se utiliza esta autenticaci\u00f3n tradicional si ya se tiene una sesi\u00f3n establecida, y se navega supongase al dashboard administrativo, lo que hace normalmente el servidor es que verifica que la sesi\u00f3n este activa, que el usuario este autenticado (loggeado), \u00abeste activa la sesi\u00f3n\u00bb, consulta los permisos y \u00abpinta\u00bb una p\u00e1gina completamente nueva. Pero ahi hay un request, siempre hay un request verifica la sesi\u00f3n, entonces lo pinta con los permisos. Entonces en el caso de que sea un administrador que este autenticado, que hace, simplemente pinta la p\u00e1gina con todas las sesiones (o secciones) a las que el tiene acceso. Pero como generalmente las SPAs generalmente no refrescan, es decir cuando ustedes se van a un link, ella simplemente construye desde el frontend todo, nunca tiene manera de hacer un request para verificar si la sesi\u00f3n esta activa, entonces no funciona con las SPA. Tambien existe el problema de que con las <strong>REST API<\/strong>s se supone que no deberian tener estado, y todo el manejo de cookies (sesi\u00f3n), si tiene estado, es stateful. Deberia ser <strong>stateless<\/strong> segun como se dicta que se deberian implementar las <strong>API Restful<\/strong>. Otro problema es que las aplicaciones modernas funcionan con microservicios, es decir no solo es un solo servidor, sino que tengo m\u00faltiples servicios a los que me quiero conectar. Y el porblema es que las cookies no fluyen muy bien ahi. Hay una serie de mecanismos para solucionarlo, pero es costoso y es dificil de escalar. Se tendria que enviar la cookie, crear sesiones en cada uno de estos servicios, simplemente no fluyen, no es efectivo para los microservicios, y es algo que hoy en dia es super comun, mantener microservicios. <\/p>\n\n\n\n<p><strong>Cualquier control de acceso<\/strong>, Cualquier control de permisos, requiere volver a hacer un query a la base de datos. Si yo quiero saber si el usuario puede volver a listar estos productos, puede listar estos usuarios etc, se debe ir a la base de datos y realizar consultas. <strong>Porque la sesi\u00f3n no tiene informaci\u00f3n de permisos<\/strong>. Y esto esta relacionado con el tema de autorizaci\u00f3n. (Se va a evaluar utilizando el est\u00e1ndar de OAuth). Y finalmente no escala bien, por que la sesi\u00f3n es un espacio en memoria, a medida que se empiezan a tener muchos usuarios que est\u00e1n autenticados en nuestra aplicaci\u00f3n, se empieza a requerir m\u00e1s y m\u00e1s memoria, al punto que hay muchas soluciones como tener servidores espec\u00edficos, solo para el manejo de sesi\u00f3n. De nuevo se vuelve un tema muy dif\u00edcil de escalar, es un tema que empieza a consumir mucho mucho recurso de memoria. <\/p>\n\n\n\n<p><strong>Autenticaci\u00f3n con JWT<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" width=\"807\" height=\"461\" src=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-3.png\" alt=\"\" class=\"wp-image-1499\" srcset=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-3.png 807w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-3-300x171.png 300w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-3-768x439.png 768w\" sizes=\"(max-width: 807px) 100vw, 807px\" \/><\/figure>\n\n\n\n<p>La manera como cambia permite solucionar parte de esos problemas, empieza igual. Un usuario se autentica en base de datos, si el usuario existe y es correcto lo que hace el servidor, es firmar un token. No tiene que ser un JWT, un JWT es una manera de hacerlo, es un estandar pero hay muchas maneras.<\/p>\n\n\n\n<p>Incluso Spotify no usa JWT lastimosamente <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">(Pr\u00e1ctica con wireshark)<\/mark>, pero firma un token. Lo importante de este token es que este contiene incluso los permisos del usuario, dice quien es el usuario y cuales son los permisos. El token es enviado al cliente, y el cliente lo puede guardar en mecanismos como session storage, local storage o incluso en una cookie. Si es una SPA(Se va a hablar mas adelante) cuales son las preocupaciones de los JWT, de porque no deberian almacenarse en local o session storage, lo mas recomendable hoy en dia es hacerlo en memoria, o en una cookie pero con ciertos requisitos, se va a hablar mas adelante por que.<\/p>\n\n\n\n<p>Cuando se almacena este token, ya cualquier request que venga de ahi en adelante, se le envia el token. Y cuales son las ventajas? Como ayuda a las SPAs?Las SPAs ya no requieren un backend, para saber si el usuario est\u00e1 autenticado o no, por que realmente no existe el concepto de sesi\u00f3n. Simplemente el envia el token, y lo unico que tiene que hacer el servidor el backend, es verificar si el token esta firmado. Ya se habia hablado previamente de si un token esta bien firmado o no. Obviamente requiere el secret, y si es asimetrico la llave privada. Y ahora ya el backend o el servidor puede recibir, peticiones de multiples clientes, y no tiene que verificar en ningun momento ninguna sesi\u00f3n, ya los microservicios simplemente si tienen el token tienen la habilidad de poder consumir los recursos de este servidor, por lo que realmente el cliente ya, tiene los permisos es decir el cliente sabe a que tienes permisos, por que estan en el token y ya es permisivo en vez de preguntar. Ya no hay que preguntar a base de datos si tiene permisos o no, se confia claramente en que el token tiene los permisos por que fui yo el que con anterioridad, le otorgue ese token con esos permisos. Y esta es basicamente la diferencia entre la autenticaci\u00f3n tradicional, y la moderna usando JWT. <\/p>\n\n\n\n<p>Nota: (lo que va adentro del header y del payload) es completamente visible para cualquier persona que acceda al token<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Criptograf\u00eda <\/h2>\n\n\n\n<h3>SHA512 vs SHA256<\/h3>\n\n\n\n<h4>\u00bfQu\u00e9 algoritmo se recomienda usar al codificar\/decodificar tokens de aplicaciones web JWT? \u00bfEs suficiente usar HMAC-SHA256 o usar HMAC-SHA512 proporcionar\u00eda m\u00e1s seguridad? Y en m\u00e1quinas de 64 bits, \u00bfes cierto que HMAC-SHA512 es m\u00e1s r\u00e1pido que HMAC-SHA256?<\/h4>\n\n\n\n<p>Ambos algoritmos brindan mucha seguridad, cerca del tama\u00f1o de salida del hash. Entonces, aunque HMAC-512 ser\u00e1 m\u00e1s fuerte, la diferencia es intrascendente. Si esto alguna vez se rompe es porque el algoritmo en s\u00ed est\u00e1 roto y como ambos algoritmos hash est\u00e1n relacionados, es probable que ambos tengan problemas. Sin embargo, no se conoce tal ataque y la construcci\u00f3n HMAC en s\u00ed parece ser muy fuerte.<br>SHA-512 es de hecho m\u00e1s r\u00e1pido que SHA-256 en m\u00e1quinas de 64 bits. Puede ser que la sobrecarga proporcionada por el tama\u00f1o de bloque de SHA-512 sea perjudicial para los tama\u00f1os de mensaje de longitud corta de HMAC. Pero puede acelerar los tama\u00f1os de mensajes m\u00e1s grandes usando HMAC-SHA-512 con seguridad. Por otra parte, SHA-256 es bastante r\u00e1pido en s\u00ed mismo, y es m\u00e1s r\u00e1pido en m\u00e1quinas de 32 bits e inferiores, por lo que elegir\u00eda HMAC-SHA-256 si las m\u00e1quinas de gama baja pudieran estar involucradas.<\/p>\n\n\n\n<p>Tenga en cuenta que los procesadores x86 m\u00e1s nuevos tambi\u00e9n contienen hardware acelerador SHA-1 y SHA-256, por lo que puede cambiar la ventaja de velocidad a favor de SHA-256 en comparaci\u00f3n con SHA-512. <a href=\"https:\/\/crypto.stackexchange.com\/questions\/53826\/hmac-sha256-vs-hmac-sha512-for-jwt-api-authentication\">https:\/\/crypto.stackexchange.com\/questions\/53826\/hmac-sha256-vs-hmac-sha512-for-jwt-api-authentication<\/a><\/p>\n\n\n\n<p>\u00abalg\u00bb: \u00abHS256\u00bb,<\/p>\n\n\n\n<p>JWT <strong>RS256<\/strong> used for JSON web signature tokens to sign the header and the claim set.<\/p>\n\n\n\n<p>Es como una abreviatura de RSA y de SHA-256. Por lo que RSA es un criptosistema as\u00edmetrico que se basa en su clave privada y p\u00fablica, y SHA-256 es una funci\u00f3n hash com\u00fan. La idea es que con RSA se generan un par de claves (una privada y una p\u00fablica), con la privada se crean las firmas y con la p\u00fablica se pueden verificar las firmas. Con  una clave p\u00fablica no se pueden crear firmas, solo verificar.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" width=\"328\" height=\"631\" src=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-4.png\" alt=\"\" class=\"wp-image-1698\" srcset=\"https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-4.png 328w, https:\/\/blog.thepragmatic.xyz\/wp-content\/uploads\/2022\/11\/image-4-156x300.png 156w\" sizes=\"(max-width: 328px) 100vw, 328px\" \/><\/figure>\n\n\n\n<h3>Dudas<\/h3>\n\n\n\n<p>No puedes con JWT, lo que puedes hacer es poner una fecha de expiracion del token.<\/p>\n\n\n\n<p>Exacto, sesiones y JWT son temas tecnicas muy diferentes. <\/p>\n\n\n\n<p>las sesiones son del mundo de autenticaci\u00f3n con estados ejemplo estado sesi\u00f3n iniciada, estado sesion terminada. OAuth y JWT no tienen estado por ende no hay ninguna sesi\u00f3n para cerrar.<br>un usuario no autenticado es usuario sin token o sin token valido en las aplicaciones SPA como angular o react se guarda el token en el navegador y cuando se realiza el logOut se borra el token y se redirecciona a la home.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2>Pendientes<\/h2>\n\n\n\n<ul><li>Reencauchar concepto de identidad.<\/li><li>Token vencido, token revocado<\/li><li>Token JWT autofirmados<\/li><li>Sesion vs JWT.<\/li><li>Kubernetes Auth (RBAC, OIDC Tokens, Identity Provider) https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/authentication\/<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Intro Diego Cookies (Viejas) de lado cliente se puede ver la info en el header (forma insegura guardar informacion, cambiar informacion [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1197,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[23,1],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1193"}],"collection":[{"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1193"}],"version-history":[{"count":380,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1193\/revisions"}],"predecessor-version":[{"id":1741,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1193\/revisions\/1741"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=\/wp\/v2\/media\/1197"}],"wp:attachment":[{"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.thepragmatic.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}