logo

midudev


Transcribed podcasts: 167
Time transcribed: 5d 15h 37m 28s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

En el frontend lo que vamos a hacer justamente es conseguir iniciar sesión, vamos a guardar este token, vamos a iniciar sesión con un formulario, recuperaremos el token y una vez que tengamos el token haremos algo con él para guardarlo y de esta forma ya tendremos como la sesión del usuario en el frontend.
Así que vámonos a ello, vamos a recuperar nuestro proyecto que teníamos de frontend, yo lo tengo aquí, tengo el nodes app full stack bootcamp, el base URL por ahora voy a hacer que apunte a localhost porque ya hicimos un deploy en Heroku pero más adelante volveremos a hacer un deploy donde vamos a deployar a la vez el backend y el frontend.
Pero por ahora como vamos a estar desarrollando en localhost pues lo vamos a dejar y ya está, lo vamos a dejar así que funcione, me voy a asegurar que esto funciona porque hace tiempo que no lo levanto así que vamos a ver, espera que me levante el servidor, vale mira muy bien aquí tenemos las notas justamente que hemos creado, voy a hacerlo un poco más grande, bueno no sé si funciona, el filtro este creo que no funcionaba pero bueno no debería funcionar el crear una nota porque ahora mismo no tenemos el token pero podemos ver que estas notas son las que he creado antes que estaba probando pero claro yo ahora si intento crear una nota lo voy a intentar crear y vamos a ver el pete
porque debe petar, otra nota y le damos a save, ves no tengo autorización, vamos a añadirle autorización a nuestra nota, lo que vamos a hacer es volver a React, vamos a volver al frontend, vamos a tocar frontend, vamos a hacerlo en esta clase muy a saco porque me interesa que nos enfoquemos mucho en esto pero más adelante esto lo iremos refactorizando, iremos sacando componentes, iremos haciendo cosas pero por ahora lo vamos a hacer todo en app y más adelante pues eso, refactorizaremos, iremos iterando, vamos a tener aquí un estado para el username y otro username
creamos un estado ¿vale? con un string vacío y también un password, el set password y lo tenemos así, este estado se tiene que sincronizar básicamente con un formulario así que vamos a poner esto más pequeño, esto también, esto también, que estos no son importantes
ya miraré más adelante el tema del toggle importance porque eso no sé por qué, creo que no funciona porque nunca lo hicimos pero bueno, que ahora mismo no es importante
aquí entre la notificación esta, este notification, notification, lo que vamos a hacer aquí es poner un formulario ¿vale? vamos a mostrar un formulario para poder iniciar la sesión del usuario
así que voy a ir bastante rápido porque no es tan importante como hacemos el formulario, como no sé qué, handle login submit, voy a utilizar porque aquí teníamos add note
vale, pues vamos a poner un handle submit, ya os digo que esto lo sacaremos de aquí, así que por ahora un input ¿por qué? porque necesitamos un campo donde el usuario diga
bueno, yo me llamo Pepito, vale, pues el valor va a ser el del estado del username y el name, vamos a poner username, vamos a poner un playholder que sea username también
y que cuando cambiemos, pues de nuevo, esto también lo hemos visto en otra clase, pero vamos a actualizar el username ¿con qué? aquí nos llega un evento y el evento tiene event.target.value
¿qué nos gusta esto que queda un poco más largo? pues sacáis directamente el target y aquí tendrías ya target.value
con esto ya tendríamos en el estado el nombre del usuario, vamos a copiarnos esto y vamos a poner password, cambiamos el type por password
para que así salgan los asteriscos, al menos que dé la sensación que realmente es muy seguro
en value, pues nada, el password y username, password, hay username, playholder, ahora aquí es set password y esto sí, que funciona exactamente igual
y podríamos poner pues también un botón ¿no? botón login, que sea login y ya estaríamos
y este handle submit pues nos faltaría hacer el handle submit, vamos a ponerlo aquí, handle submit
¿qué tenemos que hacer cuando hagamos el handle submit? bueno, lo que tenemos que hacer en realidad sería, bueno, primero esto importante
dijimos que había que prevenir por defecto cuando se hace un submit del formulario
porque por defecto un formulario cuando hace submit hace un post al action que tenga aquí, como no tenemos ninguno
pues iría a la almohadilla, pero nosotros no queremos que haga una action, no queremos que haga nada de esto
queremos nosotros controlar que es lo que hace, así que vamos a poner aquí un console log por ahora
y this is something
esto sale por aquí, bueno, tenemos más o menos
más o menos de aquella forma, podríamos ponerle unos dips ¿no? para que quede un poquito
más, podemos poner los dips
en cada uno de los inputs ¿no? vamos a poner aquí un dip y aquí otro dip
y aquí otro dip, es que así creo que
saldrá un poco y vamos a
poner, los estilos no os preocupéis
sé que es horrible, lo sé, pero
es que tenemos otra, una clase de estilos
entonces lo haremos más adelante, lo importante es que ahora
funcione, eso es lo importante, ahora ya
tenemos aquí una forma de iniciar sesión
si le doy a aquella consola y le doy a login
pues está haciendo el submit que es justamente lo que
queríamos, pero este submit
¿qué a dónde va? ¿no? ¿no va a ningún sitio o qué?
para eso hemos hecho el backend ¿no? pues para
darle vida a nuestra aplicación, teníamos
el servicio aquí de notes, donde
estaba todo el tema de notas y tal
bueno, pues igual que tengamos un servicio
para todas las notas, hacer las requests, para crear
para update, para bla bla bla, vamos a hacer una que
sea pues no sé si llamarle users
o como le llamamos, login, como
más parecía que teníamos antes, aquí sí que
podemos utilizar imports ¿vale?
que he estado a punto de utilizar otra vez el const
pues import, axios, from, axios
¿y qué tendríamos que hacer? bueno
aquí tenemos el base url, vamos a
copiarnoslo exactamente aquí, lo que pasa
es que aquí la API tiene que ir al login
que es la que hemos creado, vamos a crear la
función de login, vamos a hacerlo con
async await, credentials
y aquí pues utilizamos axios
y nos vamos, vamos a guardar la respuesta
vamos axios punto post
y esto, base url
y vamos a utilizar los credenciales, pero
bueno, esto debería funcionar correctamente
a la hora de hacer login, cuando hacemos el login
la respuesta con axios
tenemos en data tendríamos toda la respuesta
así que vamos a hacer esto
y sacamos directamente data de response
y la devolvemos, esta data
al final esta data es la que se supone
que va a tener la información que nos interesa
para la sesión del usuario
vamos a ver si esto funciona ¿no?
va a hacerse export default del login
creo que en nota lo hicimos así ¿no?
sí, con un objeto export default
podríamos hacerlo de otra forma
podríamos exportar así, cada uno
vamos a hacer esto
¿por qué? ¿cómo estamos utilizando aquí las notas?
bueno, es que estamos utilizando
node service directamente
vale, vamos a dejarlo como estaba por ahora
ya le damos una vuelta
porque a lo mejor tiene más sentido por ahora
para ver la diferencia de qué servicio se está utilizando
ver node service punto
pero bueno, más adelante igual tiene más sentido lo otro
vamos a importar nuestro nuevo servicio
login service from punto services login
login service
vamos a ver si haces tu magia
¿dónde tenemos que hacer esto?
pues aquí, login service
cuando hacemos el handle submit
la información que tenemos aquí
en este handle submit
en este event
podríamos llegar a sacar
el usuario
y a lo mejor no necesitamos estado
pero bueno
como se suele utilizar
el estado
para guardar en inputs
en react y tal
pues lo vamos a hacer así
pero vamos a añadir otro aquí
otro estado que sea el user
no el user
el user
no el user
el user
bueno, ya me entiendes
por ahora vamos a decir que es null
que no tenemos usuario
para que cuando el login service
pues funcione bien
pues guardemos justamente ahí
el usuario
si es caído bien
como necesitamos
hemos puesto handle submit
no sé si ponerle handle login
que a lo mejor tiene un poco más de sentido
que handle submit suena muy en general
vamos a hacer que esto sea asíncrono
para poder utilizar async await
si queréis utilizar promesas
utilizad promesas
yo voy saltando justamente
pues para ir cambiando
y para que veamos un poco de todo
pero si os gustan más las promesas
ya sabéis que no pasa nada
login service
punto
login
y ahora tenemos que pasarle los credenciales
¿cuáles son los credenciales?
username y password
username y password
que es justamente lo que hemos guardado aquí
o sea esto es porque el nombre
es exactamente igual
el del estado
con los parámetros
que espera este servicio
y que les tenemos que enviar
justamente al post
o sea ha ido todo genial
pero si no
pues tened en cuenta
que a lo mejor tendríamos que cambiar aquí
y poner otra cosa
pero esto como es
el nombre de la propiedad
y el valor es el mismo
lo podemos poner una vez
es un shorthand que se dice
y con esta forma
pues lo podríamos simplificar
ahora que tenemos esto
teníamos aquí una wait
y tendríamos el usuario
pues hacemos un set user
del user
podríamos resetear también
el set username
y el set password
porque no tiene mucho sentido
que se queden ahí
podríamos dejarlo
pero bueno
lo vamos a resetear
¿vale?
set password
así estaremos seguros
de que realmente
ha iniciado sesión
aunque podríamos enseñar
también un mensaje
el problema que tienen los awaits
que es
pues nada
que hay que hacer un try catch
cuando hay un error
a veces
es más
aunque el código queda como síncrono
que no significa que sea síncrono
visualmente
que queda síncrono
pero
hay veces que
que es un poco coñazo
a lo mejor
hay veces que las promesas
se entienden un poco mejor
justamente por
aquí en este caso
tampoco es que las promesas
quedasen tan mal
porque más o menos lo mismo
creo que teníamos un
esto
set error message
teníamos ya
si había un error
lo que sea
bueno pues podríamos poner
no sé si esperarnos
al error
y ver lo que nos devuelve
si no recuerdo mal
cuando hacíamos login
nos decía token inválido
o lo que sea
bueno
podríamos poner aquí
ground credentials
o error
o lo que sea
y después de un rato
vamos a quitar este error
porque el error
vamos a mirar el error
error message
a ver dónde se está utilizando
error message
vale
aquí en notification
esta notificación
queremos que desaparezca al rato
no queremos que se quede ahí
y que el usuario se sienta mal
por haberse equivocado
con el login
pues vamos a hacer
que después de
5 segundos
o

5 segundos
el error message
vuelva a ser 0
o null
o vacío
vale
para que desaparezca
vamos a ver
si esto funciona
porque entiendo que esto
debería ser todo
lo que necesitamos
vamos a ver
a ver que aquí
vale
el usuario es que todavía
no lo estamos usando
pero bueno
lo usaremos
por ahora queremos ver
si el login este funciona
voy a volver a mi proyecto
del backend
porque tenía la contraseña
que estamos utilizando
de nuestro usuario
la midu password
es midu def
y midu password
no es mi contraseña real
por si alguien se lo está preguntando
midu def
y la midu password
le doy a login
ha desaparecido
veis que ha desaparecido aquí
el username y el password
esto significa
que debería tener
la información del usuario
el problema es que
claro
como tampoco
no he tenido muchas luces
y no he puesto aquí
pues un console log
del user
para ver que teníamos
pues tampoco
que
ground credentials
vale
que me está guardando ahí
vete a saber que
tenemos miguel
tenemos el token
tenemos el username
o sea ya tenemos esta información
ya la tenemos guardada aquí
de forma que el usuario
en realidad ya se está
está iniciando sesión
pero no estamos manteniendo sesión
tenemos al usuario ahí
¿qué pasa?
pues que
aquí tenemos el login
tenemos el formulario aquí
aquí tenemos para crear una nota
y se está mostrando los dos a la vez
lo cual no tiene mucho sentido
porque si un usuario
no tiene la sesión iniciada
no debería haber
la posibilidad de crear notas
¿no?
así que
vamos a hacer algo
en las notas
que es esto
vamos a ponerle un playholder
también para que quede un poco
playholder
para diferenciar más que nada
¿y qué ponemos aquí en playholder?
write your note content
este formulario
y el de la inicio de sesión
este de aquí
son incompatibles
no pueden estar los dos a la vez
¿y qué es lo que me determina?
que tenemos que enseñarle
el formulario de inicia de sesión
y el de escribir la nota
pues básicamente
si tenemos un usuario
en el estado
así que
una cosa que podríamos hacer
es pintar una u otra
utilizando el renderizado condicional
que también vimos
en la clase anterior
os voy a enseñar una mala práctica
pero lo vamos a hacer
porque lo hace mucha gente
y entonces quiero que lo veáis
pero a mí no me gusta
pero bueno
os lo voy a enseñar
una cosa que se suele hacer
es crear una constante
y tener aquí un render login form
esto es un método
y este método
lo que hace
el login form
pues sería este ¿no?
form form
este login form
y por ahora
seguramente lo dejaremos así
porque así nos da la tiempo
de hacerlo todo
tendríamos una constante
que lo que hace
bueno una constante
un método
que lo que hace
es que cuando lo llamas
ejecuta
al ejecutarlo
devuelve el formulario
de login
pues esto mismo
lo vamos a hacer
con el de
render create node form
vamos a ser un poco descriptivos
al menos
ok
y ahora vamos a sacar esto de aquí
y lo vamos a poner aquí
de esta forma ahora
si queremos renderizar uno u otro
pues nada
render login form
y render node create node form
lo vamos a poner juntos
porque de esta forma
se van a ver un poco más fácil
voy a guardar los cambios
vamos a ver si esto funciona
ahora deberían estar juntos
tanto el escribir la nota
como el login
o sea que si
están funcionando bien
al final tú puedes tener un método
que devuelva JSX
y renderizarlo
pero como hemos dicho
no queremos que los dos
se rendericen
esto de sacarlo un método
que ya os digo
que a mí no me gusta
ya os explicaré por qué
se suele hacer justamente
para que aquí quede
mucho más condensado
y puedas hacer un renderizado
condicional
entendiendo lo mejor
porque si lo haces
a saco
es muy difícil de ver
es muy difícil de leer
esta puede ser una buena práctica
esto sí que es una buena práctica
el hecho de condensar tu render
para entenderlo mejor
lo que no me parece
tan buena práctica
es hacer esto
este tipo de métodos
hay que tener en cuenta
que esta constante
se va a crear
cada vez que se renderice
tu componente
hay gente que puede llegar a más
y estar tentada
a hacer un use memo
por ejemplo
que el use memo
es un hook
que lo que hace
es guardar
esta variable
y no volver a generarla
en cada render
pero esa no es
la forma correcta tampoco
si te fijas
realmente
este render create not form
es un
exacto
muy bien
es un componente
vale
entonces
si tú ves esto
que parece un componente
huele a componente
y funciona como un componente
entonces
haz un componente
ok
no hagas cosas raras
esto
el problema que tiene
es que además de que
es esencialmente un componente
no es reutilizable
y tiene alguna
algún problema de performance
en este sentido
que esta constante
y esta se van a estar generando
cada vez
que se renderiza este componente
lo ideal
sería crear
un componente
que se llame por ejemplo
login form
y ya está
pero no hay que
crearlo dentro
vale
la forma correcta
no sería esta
si tienes un componente
dentro de otro componente
hay que sacarlo de ahí
no es correcto tampoco
lo ideal
sería sacarlo
y todo lo que sea
todo lo que tiene que hacer aquí
es set username
todas las cosas que hace por aquí
esto lo debería llegar por props
set username
lo que sea
también sería mala práctica
también poner set username
yo no pondría tanto
set username
cosas así
¿por qué?
porque eso es como
lo que hace realmente
lo que estás haciendo
entonces
lo que tienes que pensar
es que hace el login form
no que utiliza
para actualizar
porque esto es
vale setea el estado
pero esto no lo debería ser
tenemos que decir
que si es un login form
pues handle
change
username
y esto
que sea una función
que sí que actualice el estado
vale
pero por ahora
lo vamos a dejar así
pero solo quiero que sepas
un poco por donde van los tiros
para que no pienses que esta es la forma correcta
ya lo iremos cambiando
iremos separando los componentes
y es solo para que lo sepas
pero
quería darte un poco de
de contexto
luego este return
igual también lo podemos quitar
podemos hacer así
podemos hacer así
porque cuando queremos ejecutar
justamente
devolverlo primero
pues no necesitas el return
puedes hacer que sea
implícito
y esto sería
una forma de renderizar
pero ya os digo
no
tiréis de esto mucho
vale
solo lo justo
lo interesante es
cuando se tiene que renderizar
el login form
bueno pues cuando el usuario
es igual a nul
entonces renderizo el login form
y el
creating form
pues cuando el user
es diferente a nul
entonces renderizo esto
esta sería una forma de hacerla
esto debería funcionar
bueno de hecho ahora vemos
que tenemos aquí
si guarda la contraseña
uff
tengo 17 contraseñas
hackeadas
Dios
no os preocupéis
son solo de páginas
que no utilizo mucho
entonces
ya tenemos el login aquí
si le doy a login
veis ahora sí que me sale
lo de create node
esto se puede hacer
de una forma mejor
obviamente
que es con una ternaria
esto lo vais a ver
mil millones de veces
esto es el renderizado
condicional en estado puro
le decimos
cuando tenemos usuario
pues hacemos un render
login form
y si no
pues lo que vamos a hacer
es renderizar
el create net form
y esto pues queda
mucho más legible
que bueno
más legible o no
eso ya cada uno
que opine
pero si tenemos usuario
renderizame el login form
perdona
esto va al revés
veis lo rápido
que lo he leído
como me ha ayudado
a encontrar el problema
si tenemos usuario
pues renderiza
el create node form
que no
pues el login form
así que
una cosa que yo recomiendo
es utilizar
render create net form
y no poner
create node form
o sea
al menos
que ya que es una mala práctica
al menos
que el método
quede claro
que hace exactamente eso
hay gente que hace esto
create node form
y es raro
a mí me parece raro
porque cuando lo leo
me da la sensación
que va a hacer otra cosa
que no renderizar algo
a mí me gusta poner render
justo delante
aunque normalmente
es una mala práctica
como os he comentado
tendríamos ya esto
le podéis dar la vuelta
si os fijáis más
de que no sea false
y tal
pero bueno
esto es
si es truci
create node form
y si no
login form
hasta aquí bien
parece que funciona
me logueo
sale la nota
obviamente
ahora lo que me faltaría
es crear la nota
porque si yo aquí
ahora me pongo a escribir
aunque tengo al usuario
el usuario no sirve para nada
porque me dice
que no está autorizado
y esto es mentira
porque sí que está autorizado
porque yo
me estoy logueando para algo
entonces vamos a arreglar esto
teníamos lo del set user
que lo habíamos hecho ya
¿no?
set

claro
como lo vamos a hacer
set user
aquí
y aquí teníamos el usuario
entonces
vamos a ver
donde se está creando la nota
vamos a ver
donde se está creando la nota
aquí
no esto es para el toggle importance
por ahora vamos a olvidarnos de eso
vamos a enfocarnos
en el de añadir nota
aquí en añadir nota
ya veis que además
le estamos enviando información
que ya no necesita
por ejemplo el date
esto no es necesario
el id
tampoco es necesario
el important
bueno sí
puede ser
esto sí
tiene sentido
pero tanto la id
como la fecha
eso ya lo hace el backend
así que se lo vamos a quitar
porque ya no tiene sentido
lo que sí que tiene sentido
es que este node service
debería de alguna forma
recuperar el token del usuario
entonces
hay dos opciones
podríamos aquí
cuando creamos la nota del usuario
aquí
como tenemos el usuario
podríamos enviarle el token también
aparte del node object
pues decir
vale
tienes el node object
pero también tienes el token
y el token es el de usuario
que tenemos justamente
en el usuario
esa podría ser una forma
y de hecho creo que vamos a hacer esa
me gusta
así que vamos a hacer esa
en el usuario
este set user
que esto es el token
directamente
bueno es la respuesta
no es el token
para el token
tenemos que hacer
token
sacar el token de user
tendríamos el token
nos vamos a notas
en el create
y aquí deberíamos tener token
vale
tendríamos por un lado
el objeto de la nota
y por otro lado
tendríamos el token
ahora
esto sí
que aquí sí
que es importante
aunque tenemos el token
como lo tenemos que enviar
ahí es donde entra
la magia de axios
tenemos que crear
un objeto config
y aquí en config
le tenemos que decir
qué headers
queremos que envíe
esta request
vale
así que
le vamos a decir
que dos headers
va a tener uno
que es authorization
importante no equivocarse
y aquí sí que le podemos pasar
el token directamente
pero el token
como hemos dicho
que no se nos olvide
que necesitamos el
bearer este
también aquí
aquí esto va token
también aquí
tenemos que ponerle
que es el string
es el bearer
y esto sería la configuración
de la request post
que vamos a hacer
así que
por un lado
tenemos base url
el objeto que le enviamos
y finalmente
tendríamos la configuración
así es como funcionaría
en este caso
ahora lo guardamos
si no he hecho nada raro
y debería aquí tener el token
que lo estamos recuperando
de usuario
le estamos pasando el token
vamos a volver aquí
me voy
voy a iniciar sesión
aquí debería tener el token
por lo tanto ahora
si escribo una nota
this is a note
le doy a save
pues aquí tenemos la nota
como se ha guardado correctamente
si ahora refresco
pues tenemos la nota
en la base de datos
ya estamos autorizando
que esta nota
la pueda crear este usuario
y que no haga nada raro
o sea
que el token
nos está funcionando correctamente
que ha iniciado sesión
sin ningún tipo de problema
y que ya lo debería tener todo bien
¿qué problema podemos encontrarnos
un poco con todo esto
que estamos haciendo
con lo que hemos hecho
que no está mal
que está bastante bien
lo que hemos hecho
a mí me gusta
el hecho de que le puedas pasar
por parámetro esto
pero luego más adelante
veremos que vamos a querer
guardar esta información
de una forma más centralizada
¿no?
el token
¿por qué?
porque si vamos a notas
fíjate
el update
también necesita el token
entonces que vamos a pasar
aquí el token
otra vez
y tal
bueno
podríamos
como más adelante
veremos Redux
y hay información
que tendremos en un estado global
que ya veremos
lo que es el estado global
y todas estas cosas
una cosa que podemos hacer
justamente
y lo cambiaremos más adelante
es que las notas
tengan alguna forma
de guardarse el token
en lugar de tener que pasárselo
continuamente
lo que podemos hacer
es que aquí en notes
tengamos el token
y le vamos a decir
que por ahora es null
y vamos a tener un método
que le vamos a llamar
setToken
que va a recibir el token
bueno
en lugar de token
le vamos a dar a new token
para que se llame de otra forma
y este token
lo que vamos a hacer es
vale
pues el token
va a ser
bearer new token
y este método
setToken
que lo vamos a exportar
por aquí
lo que vamos a hacer
es
vale
esto lo guardamos
este método
setToken
que está guardándose el token
lo que vamos a hacer
es utilizarlo aquí
así que en lugar
de guardar de aquí
del token
y todo esto
esto token
fuera
todo esto fuera
lo que vamos a hacer
cuando se hace el handle login
y hace este setUser
que parece que tenga
el token ahí
lo que podemos hacer
justamente
es guardarnos
también el token
en el servicio
luego veremos
cómo mejoramos esto
o sea
esto es una forma
un poco de
salir del paso
por ahora
pero
iremos mejorando
todo se itera
así que ahora
nuestro node service
hace un setToken
guarda el token
y por lo tanto
aquí va a tener
el token siempre disponible
ahora este token
que tenemos aquí
que al principio es null
pero cuando llegamos
al setToken
cambia
esto sería utilizando
los módulos
para guardar información
porque este módulo
se guarda en memoria
y es compartido
o sea que está teniendo
como un pequeño estado ahí
pues lo que vamos a hacer
es que aquí
en lugar de hacer
headers
authorization
y hacer esto
esto ahora ya directamente
es el token
porque aquí sí
lo estamos guardando
ya con el bearer
y todo esto
así que
vamos a ver
este token
ya no lo necesitamos aquí
no lo utilizamos
este tampoco
de esta forma
incluso podríamos
este config
bueno
vamos a poner por aquí
vamos a copiar
pero incluso hasta el config
este lo podríamos
lo podríamos cambiar
vamos a poner esto aquí
y ya tenemos el update
y el create
ya lo tendríamos con el token
vamos a ver si esto
que hemos hecho funciona
claro que yo he estado
aquí ya dándole caña
vamos a ver si funciona
vale
save
bueno parece que funciona
y sí
ahí está
vamos a ver si funciona
pues funciona
perfecto
ahora
hay un problema
supongo que te has dado cuenta
que cada vez que estoy
yo hago el login
aquí hago
vamos a ver
si esto funciona
hasta aquí el vamos a ver
perfectamente
pero
el tema es
que si yo refresco
para ver si esto se ha guardado
pam
me sale otra vez el login
esto tiene bichos
esto tiene bichos
porque
porque hombre
hemos dicho que queríamos
tener una sesión en el usuario
por lo tanto
tendremos que hacer alguna cosa
para que esto persista
las sesiones
la gracia que tienes que persistan
si no persisten
no son sesiones
ni son nada
son otra cosa
así que vamos a hacer
que persista de alguna forma
de nuevo
esto lo iremos iterando
pero por ahora
tenemos que encontrar
alguna forma de que persista
esta sesión
como lo vamos a hacer
bueno pues ya que tenemos aquí
este set token
lo estamos haciendo aquí
lo que podemos hacer
es guardarnos este token
en algún sitio
donde nos lo vamos a guardar
por ahora
nos lo vamos a guardar
en local storage
¿por qué?
porque es el sitio más típico
donde se guardan
normalmente
la forma
que mucha gente dice
que es más correcta
sería utilizar una cookie
y utilizar lo que se llama
un server site session
¿vale?
tener la sesión
en la parte del servidor
utilizar una cookie
http only
y que esto
debería evitar
ciertas cosas
ahora te explicaré
porque eso
no siempre es verdad
pero es verdad
que te da
una cookie
http only
y además
utilizar
sem site
sería la opción
más correcta
¿vale?
pero por ahora
tenemos esto
por aquí
logget
node
app
user
json.stringify
y vamos a guardar
el usuario
como un string
porque en el local storage
no podéis guardar un objeto
lo tenéis que guardar
como un string
no se puede guardar
un objeto
se puede guardar un objeto
pero como string
luego lo tenéis que volver
a cambiar
así que
ahora cuando hagamos
el login
de hecho
podríamos intentarlo
y así veremos
si hacemos el login
y ahora me voy a application
y miro aquí
mi local storage
aquí tengo un montón
de cosas
de todas las cosas
que tengo en el localhost
pero deberíamos tener una
que sea este
log
node
app
user
fíjate lo que me ha guardado aquí
object object
¿por qué?
porque ha intentado ejecutar
el toString
y no le ha gustado
bueno sí que le ha gustado
porque le da igual
no ha preguntado
tampoco ha dicho
ah bueno a mí me parece bien
pues esto ha hecho
hay que hacer esto
¿vale?
hay que guardarlo
como una string
hacer un stringify
y esto lo que sí que nos va a hacer
es guardarlo correctamente
como esperamos
fíjate que Chrome
ya sabe
que normalmente
guardamos objetos
así como strings
y que aquí
me lo está formateando
correctamente
porque ya detecta
pero esto
es un string
lo que estamos guardando
es un string
no es un objeto
es un string
luego lo transformamos
en un string
y lo que sea
pero aquí tenemos
la información ya
con nuestro token
y tal
este token
obviamente pues
expirará
con el tiempo
que hemos dicho
antes que expire
que en nuestro caso
creo que eran 7 días
si no me equivoco
pero lo importante ahora
es que al menos
estamos guardando el token
ahora es explicar una cosa
sobre esto del token
los problemas que puede tener
las ventajas
que sería una cookie
y desventajas
y por qué hay mucho
y por qué no te deberías
preocupar excesivamente
en tu caso
pero bueno
ahora lo explico
antes de esto
vamos a darle vida a esto
porque yo aunque
aquí refresco
y me sigue saliendo
yo me he guardado aquí el token
sí pero no lo estamos usando
todavía el token
lo que vamos a hacer
es que en nuestra aplicación
que ya la aplicación
nos está pidiendo a gritos
que a ver si nos ponemos
a separar en componentes
que menos mal
que lo vamos a hacer pronto
porque si no
esto no
no vamos a poder leerlo
mucho más
vamos a añadir otro efecto
esto es una de las preguntas
que me hicisteis un montón
en una de las clases
se puede tener más de un efecto
se pueden tener tantos
como queráis
pero cuanto menos tengáis
más entenderéis
vuestro componente
súper importante
en este caso
vamos a utilizar
otro
otro efecto
vale
vamos a utilizar otro efecto
que solo sea
para leer
el local storage
esto más adelante
lo iteraremos también
pero por ahora
necesitamos alguna forma
de recuperar
si el usuario
pues está
con la sesión inicial
hacemos un log
user json
¿de dónde sacamos esto?
del window
local storage
punto get item
y aquí tendríamos la id
que estamos utilizando
ahora alguien me preguntará
porque seguro
no estoy viendo el chat
pero alguien me preguntará
oye ¿por qué pones window?
¿qué te pasa?
estás tonto
¿por qué no pones local storage
directamente?
buena pregunta
a mí personalmente
me parece una buena práctica
siempre poner
de dónde salen los métodos
obviamente
si este local storage
al final es una propiedad
de global
va a funcionar sin problemas
pero
es mágico
de alguna forma
¿no?
no estás siendo consciente
o no lees exactamente
de dónde está saliendo esto
podrías tener un paquete
en npm
que se llame local storage
y utilizarlo
de hecho
alguno hay
entonces
a mí me gusta
personalmente
decir de dónde
salen las cosas
a mí
si no gusta poner
window.localstorage
pues bueno
utilizar local storage
directamente
pero
es una práctica
que veréis
que yo hago un montón
cuando utilizo
pues local storage
sesión storage
cualquier cosa del window
incluso el fetch
lo hago de window.fetch
no lo saco
a no ser que
utilice un paquete
que se llama fetch
y lo utilice y ya está
de hecho hay
incluso reglas del linter
que te lo pueden decir
hay algunas reglas del linter
que te dicen
oye
evitar métodos
que sean de sitios globales
vale
si tenemos el json
del usuario
que está logado
vamos a crear
vamos a recuperar
el usuario
parseando este json
vamos a parsear
y una vez que tenemos
el objeto del usuario
vamos a hacer un set user
porque esta es la información
al final que estamos
recuperando en el login
ves en el login
estamos recuperando
esta información
y la estamos guardando
en estado
bueno pues vamos a actualizar
el estado
en este caso
con la información
del usuario
y además tenemos
que poner el node service
el set token
para que las notas
el servicio de notas
tenga este token
que estamos utilizando
así que ahora
guardamos los cambios
tenemos este efecto
importante
le hemos puesto
una dependencia
o sea
le hemos puesto
el array de dependencia
vacío
de forma que esto
se va a ejecutar
solo la primera vez
o sea
cuando se rende dice
por primera vez
nuestro componente
pasará por este efecto
y ya está
vamos a ver si esto funciona
bueno
ahora ya
he refrescado
y puedo ver que
me aparece directamente
lo de escribir
una nueva nota
si yo ahora escribo
una nueva nota
probando
y le doy a save
parece que funciona
si yo ahora refresco
pues sigue estando aquí
el formulario
de crear notas
no el de iniciar sesión
si me voy a la aplicación
al local storage
y borro justamente
porque bueno
aquí tengo un montón
de cosas de
bueno
de proyectos que son
en el mismo
voy a borrarlo todo
si ahora refresco
no tengo nada
en el local storage
de nuevo tengo
la
inicio de sesión
tengo que iniciar sesión
me vuelvo a guardar
refresco
ya lo tengo aquí
entonces
podríamos fácilmente
poner un logout
si alguien se lo pregunta
podríamos hacer un logout
con un set user
limpiar el local storage
y tal
haríamos un set user
y set user null
y limpiar el local storage
set token null
y todo esto
de hecho a ver
poner el logout
os lo dejo
no lo hacemos del todo
pero sería algo así
node service.set token
está bien que lo veáis
porque por aquí van
un poco los tiros
de las cosas
que necesitaremos
más adelante
ya vemos que
tenemos como una información
ahí que
cuando separemos esto
en componentes
vamos a necesitar
entonces está bien
que veamos
por qué vamos a necesitar
las cosas
en este caso
lo tenemos todo
en un solo archivo
a saco
pero ya os he ido diciendo
malas prácticas
entonces vamos a tener
que iterar este
este componente
y toda esta información
pues de alguna forma
tendremos que
estas acciones
que pensamos de
iniciar sesión
cerrar sesión
todo esto
en realidad son acciones
que hace el usuario
en las que tienen
un impacto
en la UI
por lo tanto
veremos una forma
de articular esto
mucho mejor
si queríamos hacer
un botón de logout
pues podríamos hacer esto
set user
pues null
node service
tal
y window
local storage
pues podríamos eliminar
justamente el item
o podríamos limpiar
todo el local storage
lo que queráis
podríamos hacer esto
y en el formulario
de crear
por ejemplo
las notas
que es justamente
cuando ya tenemos
la seguridad
de que
está el usuario
pues
cuando clicamos esto
al final
he dicho que no lo iba a hacer
y lo estoy haciendo entero
pero bueno
no pasa nada
para eso estamos
cerrar sesión
vamos a poner un div
aquí para que esto
esté separado
ya arreglaremos
los estilos
no os preocupéis
ya sé que está feo
bueno tenemos aquí
cerrar sesión
le damos
veis
y ya está
y ahora si refresco
pues nada
ya tenemos una forma
de cerrar la sesión
súper rápido
súper fácil
y súper
súper
vale
pues ahora que
ya tenemos todo esto
os voy a comentar
rápidamente
por qué realmente
local storage
tiene tan mala fama
por un lado
y por otro lado
os voy a comentar
el tema de las cookies
es una cosa rápida
pero creo que es interesante
¿no?
y por qué no te tienes que preocupar
tanto en React
y vamos a ver por qué
el tema
es que React
te está
arreglando
el hecho de que
no te tengas que preocupar
de los ataques
de inyección
de scripts
en tus aplicaciones
a no ser que lo fuertes
¿qué quiere decir esto?
imagínate
que cuando creamos una nota
donde tenemos
en la formulario de crear notas
aquí
cuando creamos una nota
claro
aquí en el valor
de new note
aquí
en este write note
voy a hacer esto
yo pongo esto
pongo algo así
script
alert
hola
hago algo así
¿no?
o sea
guardamos un script
le voy a dar a save
¿vale?
y esto me lo ha guardado así
¿no?
como por suerte
este script
o sea yo he escrito
un script así a mano
y cuando lo pone aquí
lo está poniendo como texto
si yo lo inspecciono
vas a ver aquí
que esto
lo está entendiendo
como texto
no lo está entendiendo
como que realmente
es una etiqueta HTML
por suerte
porque si lo estuviese
entendiendo como una etiqueta HTML
estamos medio despedidos
pero por suerte no
¿qué está haciendo React?
de hecho por esto
es una de las razones
por las que se creó React
para evitar este tipo de ataques
que son tan comunes
súper comunes
es uno de los problemas
de seguridad
más típicos
de las páginas web
en las que un usuario
de hecho en MySpace
hay una historia muy buena
que en otro directo
si queréis la repasamos
de uno de los mayores ataques
que tuvo una red social
con MySpace
donde un chico
consiguió miles y miles
de amigos
gracias a este
a este
bug
bueno bug o ataque
hacker
a la hora de inyectar
código JavaScript
entonces
nosotros hemos hecho esto
y esto se ha guardado
en la base de datos
pero por suerte
React
cuando justamente
estamos en las notas
aquí en este componente
y lo está renderizando
cuando llega
al contenido
de la nota
pues este
node content
no lo está entendiendo
como que sea algo
que tenga que
que entender
que es HTML
pero que pasaría
vamos a ver si esto funciona
no tengo ni idea
pero igual
podemos ver el error
existe en React
una forma de que tú
digas
no tú esto me lo renderizas
como HTML
o sea
esto me lo
a ver
Dangerous setting
en el HTML
tú le puedes pasar
una prop
donde le digas
no no
yo sé que lo que está
introduciendo esto
esto es bueno
esto es
esto es de fiar
esto es de fiar
entonces tú le puedes decir
no renderízame
como HTML
y vamos a ponerle
que diga el node
content este
vamos a poner esto
vamos a ver si esto funciona
bueno
vale
no lo ha hecho
pero fíjate que ya no aparece
o sea
fíjate que ya no aparece
me gustaría ver
por qué no lo ha detectado
pero lo que sí que vemos
es que el contenido
no aparece
¿vale?
pero fíjate
sí que lo ha detectado
aquí como script
y como un alert
y tal
no lo ha ejecutado
por suerte
pero
ya vemos
que en realidad
esto
¿ves ahora que
el script
tiene otro color?
es porque han entendido
esto como un
como un script
en línea
porque realmente
lo que estamos haciendo aquí
es inyectar
javascript
en nuestra nota
y claro
lo que estamos haciendo
al renderizar esto
pues que ya tenemos esto
una vez que tú haces esto
nada te impide
hacer algo como
yo que sé
local storage
punto get item
poner un script
en línea aquí
vamos a poner algo así
const item
algo así
ponemos aquí la nota
vamos a ver
cuál era la key
del este
que por desgracia veo
no sé
por algo que se me escapa
veo que no se ejecuta
pero
no debería ser imposible
vamos a poner
console.log
del
item
a ver si cuela
que no creo
pero
pero ya veis que no se renderiza
por desgracia no lo hace
no sé si es que ría
que está haciendo alguna magia
por ahí
pero si fuese html
esto se lo comería
con patata
pero es raro
igual sé que debería funcionar
igual se me está capando algo
a ver si alguien
ve algo
pero
obviamente
ya os digo
no hagáis
no hagáis
excepto tengáis un muy buen motivo
utilizar esta prop
porque al final
lo que está haciendo es
renderizar
ese contenido
como html
sin ningún tipo de escapado
sin intentar controlar
este tipo de ataques
en este caso
no sé por qué funciona
no funciona
pensaba que a lo mejor
funcionaría sin problema
no sé si ría
que está haciendo también
alguna magia por ahí y tal
el tema es
que al menos
ya estáis viendo
que está detectando
este script aquí
ya no lo está renderizando
como si fuese texto
ni nada
y esto sería una forma
de inyectar código
una vez que esto
lo puedes ejecutar
que ya os digo
que esto yo lo he visto
funcionando sin problemas
y yo me he pasado pipa
con un montón de páginas
que tenían este tipo de ataques
al final
este console.log
que hemos hecho aquí
también podrías llevarlo
más allá
y podrías hacer
un fetch
por ejemplo
a una página
que fuese
https
myweb
no sé qué
y aquí pues pasarle
por ejemplo
el item
y aquí ya tendría el token
ya está
así de fácil
ya tendría el token
esto es un ejemplo
de mil millones que hay
hay miles de ejemplos
por ejemplo
en los típicos
ah mira ahora
si que está esto
como si fuese un
hay otros
por ejemplo
pon aquí tu
la url de tu imagen
y tú
en la url de la imagen
en lugar de poner
la url de la imagen
pues tú pones
claro
ellos esperan que hagas
pues midudez.imagen.png
y tú haces

pues esto
.png
termino esto
on error
y aquí en error
tú puedes poner javascript
ah pues cuando hay un error
pues aquí tengo el item
igual local storage
.getitem
y ya sabes un poco lo mismo
entonces
una vez que ya estás guardando
el token
en realidad
lo más
lo más preocupante
aparte de que alguien
tenga acceso directamente
a tu máquina
es el hecho de que pueda
tu página
tener este tipo de posibilidad
de ataque
porque entonces
la puedes liar mucho
react
como puedes ver
esto te lo
te lo soluciona
por defecto
cualquier contenido
que tú renderices así
no te lo va a ejecutar
y te lo va a hacer así
y esto es una gran ayuda
algo de lo que no te tienes
que preocupar
para nada
entonces
si es en local storage
o ya sea en cookie
o ya sea en cookie
http only
en esas tres
si tienes un ataque
xss
la leo
que es lo bueno
que ahora
está el site
same site
cookies
hay un nuevo tipo de cookies
es bastante nuevo
que se llama
same site
esto no significa
que seas invulnerable
a los ataques
incluso con xss
pero sí que es verdad
que puede ser un poco
más estricta
de forma que
puedas hacer que
tenga que ser
al mismo dominio
que la cookie
que tienes
la tengas que enviar
solo al mismo dominio
o sea que no puedas
hacer lo que he dicho yo
de hacer un fetch
y enviar la cookie
o el token
a cualquiera
o sea
podrías tener
una cookie
con http only
con un same site
que además
sea estricta
que sea
no se le puede enviar
a ninguna
web que sea externa
solo podría ser
del mismo dominio
estricta
por defecto
no es estricta
o sea que además
habría que añadirlo
y este same site
no todos los navegadores
lo soporta
creo que por ejemplo
internet explorer
no lo soporta
pero bueno
internet explorer
tiene demasiados agujeros
como para preocuparse
lo ideal
seguramente
sería utilizar cookies
http only
con un same site
que sea estricto
pero esto complica
las cosas
complica un montón
de cosas
también
no solo a la hora
de trabajar con ello
obviamente
todo lo que sea
añadir seguridad
normalmente complica
ciertas cosas
lo compensa
seguro
en este caso
nosotros
no lo vamos a ver
porque habría que hacer
un montón de cambios
pero quería darte
este contexto
un poco
de cuál sería
la mejor práctica
eso sí
no lo vamos a ver
no lo vamos a ver
no lo vamos a ver