No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Curso Profesional de Next.js

Curso Profesional de Next.js

Oscar Barajas Tavares

Oscar Barajas Tavares

Autentic谩ndonos en la API usando Axios

12/31
Recursos

Aportes 9

Preguntas 5

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

con {data:access_token} NO estamos accediendo a access_token dentro de data, simplemente estamos renombrando la constante data a access_token. Se explica de forma equivocada y es bueno tener esto presente porque se ocupa mucho desde las nuevas versiones de ES

Si a alguien al igual que yo intent贸 utilizar nombres de variables de entorno m谩s cortos como los que pongo abajo:

API_URL=
VERSION=

Pero a la hora de probar el Login obtuvieron un error 404 porque la URL se mandaba como undefined/undefined/auth/login,
resula que, para que Next pueda leer las variables del archivo .env.local con la nomenclatura que utiliza el profesor

NEXT_PLUBLIC_EL_NOMBRE_DE_MI_VARIABLE=

Aqu铆 dejo el link de la documentaci贸n oficial de Next.js que me resolvio la duda de porque deben nombrarse de esa manera.

https://nextjs.org/docs/basic-features/environment-variables#exposing-environment-variables-to-the-browser

Espero este aporte les sea de ayuda y evite futuros dolores de cabeza como el m铆o.

Saludos y #NuncaParenDeAprender.

Clase #12: Autentic谩ndonos en la API usando Axios 12/31 馃攽


驴Qu茅 es axios?

Axios es la herramienta que nos permite trabajar con las peticiones, nos brinda recursos para poder enviar u obtener informaci贸n, adem谩s de personalizar las diferentes solicitudes a la API que estamos manejando. Fuente: aqu铆


Continuando con el proyecto: 馃敤


Para hacer la autenticaci贸n se realizar谩n los siguientes pasos:

  1. Vamos asignar el llamado a axios.
  2. Vamos importar el recurso de endPoints.
  3. Se le pasar谩n el usuario y el password del usuario al llamado por medio de axios.
  4. Se crear谩 la configuraci贸n para que pueda aceptar y trabajar la aplicaci贸n de json.
  5. Se manipular谩 el access_token el cual nos permitir谩 autenticar con la API.
  6. Se encapsular谩 el Context con useAuth y se crear谩 en LoginPage.js la constante auth ligada a useAuth y que permitir谩 acceder a signIn que recibir谩 2 valores: email y password (que se obtienen por medio de useRef()). 7. Con signIn validamos que estamos ingresando de forma correcta.


Vamos a conectar todo para que cuando se haga la petici贸n del signIn imprima por consola que ha sido exitosa la conexi贸n.

En la ruta src/hooks en el archivo useAuth.js se agrega otro import:

import endPoints from '@services/api/';


En la ruta src/components en el archivo LoginPage.js se agrega otro import:

import {useAuth} from '@hooks/useAuth';


En la funci贸n LoginPage() agregamos otra constante:

const auth = useAuth();


Tambi茅n agregamos dentro de LoginPage():

auth.signIn(email,password).then(() => {
	console.log('Login success');
});


Guardamos todo y ejecutamos npm run dev

Cuando abrimos la p谩gina, al dar click en login, podemos agregar un usuario autenticado en la API como 鈥渆mail鈥: 鈥[email protected]mail.com鈥, 鈥減assword鈥: 鈥渁dmin123鈥, si damos a Inspeccionar y network se puede escuchar lo que est谩 pasando por debajo.



鈿狅笍 Dato: Algo curioso en mi login es que sal铆an 2 peticiones una que dice: 204 No Content y otra fallida, tiene como salida en https://api.escuelajs.co/api/v1/auth/login/ el mensaje: {"statusCode":404,"message":"Cannot GET /api/v1/auth/login","error":"Not Found"} y en consola el error: net::ERR_INTERNET_DISCONNECTED

El error que ten铆a era que ten铆a mal configurado el Network (Red) del inspector de web, ten铆a seleccionado 鈥渙ffline鈥 (fuera de l铆nea), se puede seleccionar otras velocidades o 鈥渘ot throttling鈥 (sin aceleraci贸n).

Ya con esto no tuve m谩s problemas y pudo conectar de forma exitosa. 馃帀

para los que estamos en el futuro y al hacer el post les devuelve 401 no autorizado podr铆an revisar el pakage.json , la versi贸n de axios si copias al profesor al pie de la letra deber铆as usar esta versi贸n

npm i [email protected]0.27.2

Hola, para los que quieran usar fetch, aqu铆 le comparto el c贸digo:

const signIn = async (email, password) => {
		const response = await fetch(endPoints.auth.login, {
			method: 'POST',
			headers: {
				accept: '*/*',
				'Content-Type': 'application/json;charset=utf-8',
			},
			body: JSON.stringify({ email, password }),
		});
		const data = await response.json();
		console.log(data.access_token);
	};
  • useAuth.js
import React, { useState, useContext, createContext } from 'react';
import Cookie from 'js-cookie';
import axios from 'axios';
import endPoints from '@services/api/';

const AuthContext = createContext();

export function ProviderAuth({ children }) {
  const auth = useProvideAuth();
  return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
}

export const useAuth = () => {
  return useContext(AuthContext);
};

function useProvideAuth() {
  const [user, setUser] = useState(null);

  const signIn = async (email, password) => {
    const options = {
      headers: {
        accept: '*/*',
        'Content-Type': 'application/json',
      },
    };
    const { data: access_token } = await axios.post(endPoints.auth.login, { email, password }, options);
    console.log(access_token);
  };

  return {
    user,
    signIn,
  };
}
  • LoginPage.js
import { useRef } from 'react';
import { LockClosedIcon } from '@heroicons/react/solid';
import { useAuth } from '@hooks/useAuth';

export default function LoginPage() {
  const emailRef = useRef(null);
  const passwordRef = useRef(null);
  const auth = useAuth();

  const submitHanlder = (event) => {
    event.preventDefault();
    const email = emailRef.current.value;
    const password = passwordRef.current.value;

    auth.signIn(email, password).then(() => {
      console.log('Login success');
    });
  };

  return (
    <>
      <div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
        <div className="max-w-md w-full space-y-8">
          <div>
            <img className="mx-auto h-12 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow" />
            <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">Sign in to your account</h2>
          </div>
          <form className="mt-8 space-y-6" onSubmit={submitHanlder}>
            <input type="hidden" name="remember" defaultValue="true" />
            <div className="rounded-md shadow-sm -space-y-px">
              <div>
                <label htmlFor="email-address" className="sr-only">
                  Email address
                </label>
                <input
                  id="email-address"
                  name="email"
                  type="email"
                  autoComplete="email"
                  required
                  className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                  placeholder="Email address"
                  ref={emailRef}
                />
              </div>
              <div>
                <label htmlFor="password" className="sr-only">
                  Password
                </label>
                <input
                  id="password"
                  name="password"
                  type="password"
                  autoComplete="current-password"
                  required
                  className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                  placeholder="Password"
                  ref={passwordRef}
                />
              </div>
            </div>

            <div className="flex items-center justify-between">
              <div className="flex items-center">
                <input id="remember-me" name="remember-me" type="checkbox" className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" />
                <label htmlFor="remember-me" className="ml-2 block text-sm text-gray-900">
                  Remember me
                </label>
              </div>

              <div className="text-sm">
                <a href="/reset" className="font-medium text-indigo-600 hover:text-indigo-500">
                  Forgot your password?
                </a>
              </div>
            </div>

            <div>
              <button
                type="submit"
                className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
              >
                <span className="absolute left-0 inset-y-0 flex items-center pl-3">
                  <LockClosedIcon className="h-5 w-5 text-indigo-500 group-hover:text-indigo-400" aria-hidden="true" />
                </span>
                Sign in
              </button>
            </div>
          </form>
        </div>
      </div>
    </>
  );
}

== Autentic谩ndonos en la API usando Axios ==

  1. Se agrega la lectura del access_token con axios para posteriormente agregarla a la cookie.
  • Con axios.post se pueden pasar tres parametros principales:
    1er. La solicitud a la Api a consumir,
    2do. Los datos o parametros a enviar
    3ro. La configuracion de la solicitud.
  1. En este caso se utilizan los services(auth.login) para la solicitud, Los datos a enviar son el email y el password, y para la configuracion de la solicitud se crea la siguiente constante:
const options = {
            headers: {
                accept: "*/*",
                'Content-Type': 'application/json',
            }
        }
  1. /useAuth.js
const useProviderAuth = () => {
    const [user, setUser] = useState(null);
    const signIn = async (email, password) => {
        const options = {
            headers: {
                accept: '*/*',
                'Content-Type': 'application/json',
            },
        };
        //==Lectura del AccessToken que viene desde la api, para posteriormente agregarla a una cookie
        const { data: access_token } = await axios.post(endPoints.auth.login, { email, password }, options);
        console.log(access_token);
    };
  1. Se importa 鈥榰seAuth鈥 en el componente de login page para trabajar la logica.
  2. Se agrega la logica al handleSubmit:
const handleSubmit = (event) => {
    event.preventDefault();
    const user = userRef.current.value;
    const password = passwordRef.current.value;
    auth.signIn(user, password).then(
      console.log("LoginSucces")
    );
  };

Les dejo el link de la API de la escuela de javascript

https://api.escuelajs.co/docs

Les comparto el c贸digo para los que lo est谩n haciendo con TS.

  • submitHandle
const submitHandle = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (emailRef.current != null && passwordRef.current != null) {
      const email = emailRef.current.value;
      const password = passwordRef.current.value;
      auth!.signIn(email, password).then(() => {
        console.log('Te has logeado');
      });
    }
  };
  • useAuth Context
import React from 'react';
import { createContext, useState, useContext } from 'react';
import Cookies from 'js-cookie';
import axios from 'axios';
import endPoints from '@services/api';

type Props = {};

interface AppContextInterface {
  user: string;
  signIn: Function;
}

const AuthContext = createContext<AppContextInterface | undefined>(undefined);

export function ProviderAuth({ children }: any) {
  const auth = useProviderAuth();
  //para pruebas
  return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
}

export const useAuth = () => {
  return useContext(AuthContext);
};

function useProviderAuth() {
  const [user, setUser] = useState<any>(null);
  const options = {
    headers: {
      accept: '*/*',
      'Content-type': 'application/json',
    },
  };
  const signIn = async (email: string, password: string) => {
    const { data: access_token } = await axios.post(endPoints.auth.login, { email, password }, options);
    console.log(access_token);
  };

  return {
    user,
    signIn,
  };
}