Quantcast
Channel: Planeta Código
Viewing all articles
Browse latest Browse all 2733

Coding Potions: Vue ≫ Cómo crear un sistema de login y registro de usuarios

$
0
0

Introducción

Hace unos meses, ya vimos un ejemplo completo para crear una web tareas en Vue. Si no lo recuerdas te dejo el link aquí: Ejemplo de todo app en Vue.

Pues hoy tenemos otro ejemplo práctico de principio a fin para que afiances conocimientos previos con vue. En este caso vamos a hacer una web que tenga un formulario de login y un formulario de registro en Vue, así repasamos las llamadas HTTP a una API con axios y de paso aprendemos a guardar información en cookies.

🗺️ Hoja de ruta

  • [ ] 🏗️ Crear y maquetar las vistas de login y registro con formularios
  • [ ] ✨ Conectar el sistema de registro con la API
  • [ ] ✨ Conectar el sistema de login con la API
  • [ ] ✨ Recordar la sesión iniciada al recargar la página

Creando las vistas. Formulario de login y registro

Lo primero que vamos a hacer es maquetar los dos formularios, sin lógica por el momento. Para ello vamos a crear dos componentes, uno para la vista de login y otro para la vista del registro.

Ambos componentes los vamos a añadir a las rutas que tengamos en el router. Si no sabes lo que es el router de Vue te dejo el artículo que escribí sobre eso: Cómo usar el router de Vue

En mi caso en el fichero router.js pongo lo siguiente:

importVuefrom"vue";importRouterfrom"vue-router";importAppfrom"./App";importHomefrom"./views/Home";importLoginfrom"./views/Login";importRegisterfrom"./views/Register";Vue.use(Router);constroutes=[{path:"/",component:Home},{path:"/login",component:Login},{path:"/register",component:Register}];constrouter=newRouter({routes});

Simplemente tres rutas, la de la página principal que próximamente protegeremos para que solo entren usuarios logueados, la del formulario del login y la del registro.

De tal forma que lo que hago es crear 3 archivos en la carpeta views: Home.vue, Login.vue y Register.vue

La vista de login (login.vue), la he maquetado de la siguiente forma:

<template><divclass="login"><h1class="title">Login in the page</h1><formactionclass="form"><labelclass="form-label"for="#email">Email:</label><inputclass="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputclass="form-input"type="password"id="password"placeholder="Password"><inputclass="form-submit"type="submit"value="Login"></form></div></template><script>exportdefault{};</script><stylelang="scss"scoped>.login{padding:2rem;}.title{text-align:center;}.form{margin:3remauto;display:flex;flex-direction:column;justify-content:center;width:20%;min-width:350px;max-width:100%;background:rgba(19,35,47,0.9);border-radius:5px;padding:40px;box-shadow:04px10px4pxrgba(0,0,0,0.3);}.form-label{margin-top:2rem;color:white;margin-bottom:0.5rem;&:first-of-type{margin-top:0rem;}}.form-input{padding:10px15px;background:none;background-image:none;border:1pxsolidwhite;color:white;&:focus{outline:0;border-color:#1ab188;}}.form-submit{background:#1ab188;border:none;color:white;margin-top:3rem;padding:1rem0;cursor:pointer;transition:background0.2s;&:hover{background:#0b9185;}}</style>

Lo único que tiene es el formulario de login con unos estilos que me he inventado, de momento no hay nada de lógica en este componente. Siempre recordad de poner los estilos con scoped para que se queden aislados del resto de componentes.

En la imagen se ve un formulario con dos inputs, uno para el email y otro para la contraseña. Además hay un botón de enviar

Ahora vamos a añadir los v-model en los campos para poder sacar el email y la contraseña que el usuario escribe, para ello:

<template><divclass="login"><h1class="title">Login in the page</h1><formactionclass="form"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><inputclass="form-submit"type="submit"value="Login"></form></div></template><script>exportdefault{data:()=>({email:"",password:""})};</script>

No tiene más, dos v-model apuntando a variables definidas en la sección data del componente para poder recibir los dos valores. Toca preparar el método para enviar la petición de login:

<template><divclass="login"><h1class="title">Login in the page</h1><formactionclass="form"@submit.prevent="login"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><inputclass="form-submit"type="submit"value="Login"></form></div></template><script>exportdefault{data:()=>({email:"",password:""}),methods:{login(){console.log(this.email);console.log(this.password);}}};</script>

De momento solo se escriben los dos valores por consola para probar que se guardan bien en las variables los valores. Nada muy complicado de momento. Vamos a maquetar por último el mensaje de error con un v-if para que se muestre si el usuario ha metido mal el email o la contraseña:

<template><divclass="login"><h1class="title">Login in the page</h1><formactionclass="form"@submit.prevent="login"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><pv-if="error"class="error">Has introducido mal el email o la contraseña.</p><inputclass="form-submit"type="submit"value="Login"></form></div></template><script>exportdefault{data:()=>({email:"",password:"",error:false}),methods:{login(){console.log(this.email);console.log(this.password);}}};</script>

Listo, componente maquetado por el momento, vamos a maquetar el del formulario de registro para prepararlos para conectar al backend.

El componente del registro es igual solo que añadiendo un campo nuevo para que el usuario repita su contraseña:

<template><divclass="register"><h1class="title">Sign Up</h1><formactionclass="form"@submit.prevent="register"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><labelclass="form-label"for="#password-repeat">Repite la contraeña:</label><inputv-model="passwordRepeat"class="form-input"type="password"id="password-repeat"placeholder="Password"><inputclass="form-submit"type="submit"value="Sign Up"></form></div></template><script>exportdefault{data:()=>({email:"",password:"",passwordRepeat:""}),methods:{register(){console.log(this.email);console.log(this.password);console.log(this.passwordRepeat);}}};</script><stylelang="scss"scoped>.register{padding:2rem;}.title{text-align:center;}.form{margin:3remauto;display:flex;flex-direction:column;justify-content:center;width:20%;min-width:350px;max-width:100%;background:rgba(19,35,47,0.9);border-radius:5px;padding:40px;box-shadow:04px10px4pxrgba(0,0,0,0.3);}.form-label{margin-top:2rem;color:white;margin-bottom:0.5rem;&:first-of-type{margin-top:0rem;}}.form-input{padding:10px15px;background:none;background-image:none;border:1pxsolidwhite;color:white;&:focus{outline:0;border-color:#1ab188;}}.form-submit{background:#1ab188;border:none;color:white;margin-top:3rem;padding:1rem0;cursor:pointer;transition:background0.2s;&:hover{background:#0b9185;}}.error{margin:1rem00;color:#ff4a96;}</style>

En la imagen se ve un formulario con tres inputs, uno para el email, otro para la contraseña y el último de repetir la contraseña. Además hay un botón de enviar

🎉 Pues listo, primera tarea completada, hacemos commit y pasamos a la siguiente.

[X] 🏗️ Crear y maquetar las vistas de login y registro con formularios

Conectando el registro al servidor

Lógicamente para poder conectar el login y registro necesitamos un servidor (encargado de almacenar los usuarios en base de datos ya que desde javascript no se puede). Para ello necesitas una API, puedes crear tú mismo una API usando alguna tecnología de backend como nodejs, java o python. Como de lo que se trata es de aprender, para este ejemplo voy a usar esta API de pruebas ya creada que tú también puedes usar.

La API en cuestión es la de: https://reqres.in/. Te permite mandar peticions de login y registro además de muchas otras para hacer pruebas.

Lo primero que vamos a hacer es conectar el registro, para ello voy a crear una carpeta llamada logic dentro de la carpeta src del proyecto. Yo la he llamado logic pero la puedes llamar como quieras. Dentro de esa carpeta voy a crear un archivo llamado auth.js en el que voy a colocar la petición de registro y la de login.

Por el momento dentro del archivo de auth.js voy a crear esto:

importaxiosfrom"axios";constENDPOINT_PATH="https://reqres.in/api/";exportdefault{register(email,password){constuser={email,password};returnaxios.post(ENDPOINT_PATH+"regiser",user);}};

Lo primero es importar axios, si no lo tienes instalado en el proyecto ejecuta:

npm install axios --save

Lo siguiente que hago es definir una constante para endpoint de la API. Luego exporto un objeto para poder usar desde fuera este fichero con el método de registro de usuarios.

Dentro del método de registro se construye el objeto user que se enviará en la petición POST de registro de usuarios. Por último se llama a axios para que haga el POST y devuelva la promesa.

Vamos ahora a usar este fichero desde el componente de registro. Lo primero que se hace es importar el fichero encima del export default del componente:

...
import auth from "@/logic/auth";
export default {
  data: () => ({
...

¿Recuerdas el métoodo que creaste que simplemente tenía los console.log? Pues hay que cambiar eso por esto otro:

...methods:{register(){auth.register(this.email,this.password).then(response=>{console.log(response);})}}...

Como el método register del archivo auth devuelve una promesa lo que hay que hacer es crear a continuación el then para capturar la respuesta asíncrona.

Si ejecutas el código y escribes en el formulario el email eve.holt@reqres.in y la contraseña pistol y le das a registrar verás que se devuelve la respuesta de la API, en este caso un 201 created.

La forma de resolver la asincronía con el then está bien pero creo que con async/await queda todo más claro:

methods:{asyncregister(){constresponse=awaitauth.register(this.email,this.password);console.log(response);}}

Por último podemos crear una variable en el data para mostrar error si el usuario ha metido mal el usuario y contraseña. Para capturar el error en la petición podemos usar try/catch. De paso vamos a poner que si el registro es correcto lleve al usuario a la página de inicio. Veamos como queda todo el componente:

<template><divclass="register"><h1class="title">Sign Up</h1><formactionclass="form"@submit.prevent="register"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><labelclass="form-label"for="#password-repeat">Repite la contraeña:</label><inputv-model="passwordRepeat"class="form-input"type="password"id="password-repeat"placeholder="Password"><inputclass="form-submit"type="submit"value="Sign Up"></form></div></template><script>importauthfrom"@/logic/auth";exportdefault{data:()=>({email:"",password:"",passwordRepeat:"",error:false}),methods:{asyncregister(){try{awaitauth.register(this.email,this.password);this.$router.push("/")}catch(error){console.log(error);}}}};</script><stylelang="scss"scoped>.register{padding:2rem;}.title{text-align:center;}.form{margin:3remauto;display:flex;flex-direction:column;justify-content:center;width:20%;min-width:350px;max-width:100%;background:rgba(19,35,47,0.9);border-radius:5px;padding:40px;box-shadow:04px10px4pxrgba(0,0,0,0.3);}.form-label{margin-top:2rem;color:white;margin-bottom:0.5rem;&:first-of-type{margin-top:0rem;}}.form-input{padding:10px15px;background:none;background-image:none;border:1pxsolidwhite;color:white;&:focus{outline:0;border-color:#1ab188;}}.form-submit{background:#1ab188;border:none;color:white;margin-top:3rem;padding:1rem0;cursor:pointer;transition:background0.2s;&:hover{background:#0b9185;}}.error{margin:1rem00;color:#ff4a96;}</style>

Listo, sistema de registro de usuarios terminado, tarea completad, toca hacer commit.

[X] ✨ Conectar el sistema de registro con la API

Sistema de login

Una vez tenemos el sistema de registro el de login debería ser más fácil porque básicamente es repetir lo mismo que antes solo que cambiando la ruta del endpoint.

En el fichero de auth.js añadimos:

importaxiosfrom"axios";constENDPOINT_PATH="https://reqres.in/api/";exportdefault{register(email,password){constuser={email,password};returnaxios.post(ENDPOINT_PATH+"regiser",user);},login(email,password){constuser={email,password};returnaxios.post(ENDPOINT_PATH+"login",user);}};

Y en el componente de login llamamos a este fichero de la misma manera que en el registro, solo que cuando haya error activamos la variable error a true para que en el formulario se muestre un error avisando de que el email o la contraseña están mal:

<template><divclass="login"><h1class="title">Login in the page</h1><formactionclass="form"@submit.prevent="login"><labelclass="form-label"for="#email">Email:</label><inputv-model="email"class="form-input"type="email"id="email"requiredplaceholder="Email"><labelclass="form-label"for="#password">Password:</label><inputv-model="password"class="form-input"type="password"id="password"placeholder="Password"><pv-if="error"class="error">Has introducido mal el email o la contraseña.</p><inputclass="form-submit"type="submit"value="Login"></form><pclass="msg">¿No tienes cuenta?
      <router-linkto="/register">Regístrate</router-link></p></div></template><script>importauthfrom"@/logic/auth";exportdefault{data:()=>({email:"",password:"",error:false}),methods:{asynclogin(){try{awaitauth.login(this.email,this.password);this.$router.push("/");}catch(error){this.error=true;}}}};</script><stylelang="scss"scoped>.login{padding:2rem;}.title{text-align:center;}.form{margin:3remauto;display:flex;flex-direction:column;justify-content:center;width:20%;min-width:350px;max-width:100%;background:rgba(19,35,47,0.9);border-radius:5px;padding:40px;box-shadow:04px10px4pxrgba(0,0,0,0.3);}.form-label{margin-top:2rem;color:white;margin-bottom:0.5rem;&:first-of-type{margin-top:0rem;}}.form-input{padding:10px15px;background:none;background-image:none;border:1pxsolidwhite;color:white;&:focus{outline:0;border-color:#1ab188;}}.form-submit{background:#1ab188;border:none;color:white;margin-top:3rem;padding:1rem0;cursor:pointer;transition:background0.2s;&:hover{background:#0b9185;}}.error{margin:1rem00;color:#ff4a96;}.msg{margin-top:3rem;text-align:center;}</style>

Si abres la página de login y pruebas con el email: eve.holt@reqres.in y la contraseña cityslicka te debería llevar a la página principal ya que la llamada al login ha salido bien. Si pones otro email y contraseña te debería salir el mensaje de error en pantalla.

Pues otra tarea terminada. Commit y a por la siguiente:

[X] ✨ Conectar el sistema de login con la API

Recordando la sesión iniciada

Vamos con una parte fundamental en todo sistema de login, el de guardar el usuario cuando se loguea en una cookie o en el localstorage para que los componentes puedan pintar información del usuario logueado.

Para este ejemplo voy a optar por usar la librería de js cookie, para ello lo primero es decargarlo mediante npm:

npm install js-cookie --save

Ahora lo que voy a hacer es crear dos métodos más dentro del archivo de auth.js. Uno de ellos para guardar el usuario logueado y el otro para recuperarlo desde las cookies.

importaxiosfrom"axios";importCookiesfrom"js-cookie";constENDPOINT_PATH="https://reqres.in/api/";exportdefault{setUserLogged(userLogged){Cookies.set("userLogged",userLogged);},getUserLogged(){returnCookies.get("userLogged");},register(email,password){constuser={email,password};returnaxios.post(ENDPOINT_PATH+"regiser",user);},login(email,password){constuser={email,password};returnaxios.post(ENDPOINT_PATH+"login",user);}};

Lo que vamos a hacer ahora en la vista de login es que si la petición de login sale bien tenemos que guardar el usuario en la cookie. El método de login quedaría de esta forma:

...asynclogin(){try{awaitauth.login(this.email,this.password);constuser={email:this.email};auth.setUserLogged(user);this.$router.push("/");}catch(error){console.log(error);this.error=true;}}...

En el componente de registro podemos hacer lo propio en caso de que queramos que en nuestra aplicación cuando un usuario se registre se autologuee también.

Ahora en la página principal podemos mostrar el usuario logueado, para ello:

<template><divclass="home"><navigation/><h1>Home</h1>
<pv-if="userLogged">Userloggued:</p>
</div>
</template>
<script>importNavigationfrom"../components/Navigation";importauthfrom"@/logic/auth";exportdefault{name:"Home",components:{navigation:Navigation},computed:{userLogged(){returnauth.getUserLogged();}}};</script>
<style></style>

Pues listo, si has hecho login y refrescas la página verás que el usuario logueado sigue estando porque se guarda en las cookies. Para terminar podemos crear en el archivo auth.js un método para cerrar sesión que simplemente borre la cookie:

deleteUserLogged() {
  Cookies.remove('userLogged');
}

ATENCIÓN: No recomiendo guardar toda la información del usuario en la cookie, pero lo hecho así en este ejemplo para demostrar cómo guardar cosas en las cookies. En estos casos lo que se suele hacer es guardar un token y no todo el usuario. Más info de esto si buscas JWT

Pues la última tarea terminada también. Commit y listo.

La página principal la he dejado sin estilos, pero puedes aprovechar para cambiarlos.

Te dejo el proyecto subido a Codesanbox para que puedas jugar con él:

Proyecto completo en codesanbox

Y para terminar te pongo deberes por si quieres seguir aprendiendo:

  • [ ] Mostrar aviso y comprobación en el registro si las dos contraseñas no coinciden
  • [ ] Deshabilitar el botón con otros estilos mientras que el usuario no meta el email y las contraseñas no coincidan
  • [ ] Meter más campos en el registro (nombre de usuario por ejemplo) y guardar más información del usuario en las cookies

Conclusiones

Como he dicho muchas veces, mira siempre la consola del navegador porque muchas veces falla algo y no nos damos cuenta hasta que leemos el mensaje ahí.

Espero que te haya gustado este ejemplo práctico y espero que te haya servido para afianzar los conocimientos que ya tenías de Vue. Con esto deberías ser capaz de crear cosas bastante interesantes a partir de aquí.

En próximos episodios veremos cómo se pueden proteger las rutas para que solo puedan acceder usuarios logueados y ademaś veremos algún truquito más de los que puede ofrecer Vue.


Viewing all articles
Browse latest Browse all 2733

Trending Articles


Hato lada ym dei namar ka jingpyrshah jong U JJM Nichols Roy (Bah Joy) ngin...


UPDATE SC IDOL: TWO BECOME ONE


Pokemon para colorear


Sapos para colorear


Long Distance Relationship Tagalog Love Quotes


Tropa Quotes


RE: Mutton Pies (frankie241)


Ka longiing longsem kaba skhem bad kaba khlain ka pynlong kein ia ka...


Vimeo 10.7.1 by Vimeo.com, Inc.


Vimeo 11.8.1 by Vimeo.com, Inc.


Vimeo 10.7.0 by Vimeo.com, Inc.


From Male to Female


Girasoles para colorear


Smile Quotes


Ligaw Quotes – Courting Quotes – Sweet Tagalog Quotes


Re:Mutton Pies (lleechef)


Re: lwIP PIC32 port - new title : CycloneTCP a new open source stack for...


Vimeo Create - Video Maker & Editor 1.5.2 by Vimeo Inc


EASY COME, EASY GO


FORECLOSURE OF REAL ESTATE MORTGAGE