Laravel y Base de Datos

Entorno de trabajo y repaso de Laravel

1

Qu茅 aprender谩s sobre Laravel Avanzado

2

Repaso de Laravel y requisitos del curso

3

Configuraci贸n de la base de datos-SQLite en Laravel

4

Instalaci贸n, configuraci贸n y uso de Homestead

5

Instalar Laravel Sanctum

6

API de autenticaci贸n: laravel UI y laravel sanctum

Manejo de tu base de datos con Laravel

7

Capa de transformaci贸n con API Resources

8

Manejo de relaciones en bases de datos con Laravel

9

Relaciones Polim贸rficas en Eloquent

La terminal de Laravel

10

C贸mo crear comandos para la terminal de Laravel

11

Ejecutando comandos desde la API

12

Programaci贸n de tareas

Eventos y tareas de Laravel

13

Eventos y Listeners en Laravel

14

Eventos de Eloquent

15

Introducci贸n al uso de Queues y Jobs

16

C贸mo disparar eventos en Queues

17

Laravel Horizon

Manejo de errores

18

C贸mo capturar y leer errores con la clase Handler

19

Excepciones personalizadas

20

Excepciones HTTP personalizadas y debugging con Laravel Telescope

21

Configuraci贸n de logs y channels en Laravel

El coraz贸n de Laravel

22

Ciclo de vida de una aplicaci贸n en Laravel

23

驴Qu茅 son los service containers?

24

驴C贸mo funciona un service container?

25

Registro y carga de clases con service providers

Creaci贸n de paquetes

26

驴C贸mo crear mis propios paquetes de Laravel?

27

Propiedades para manejo de dependencias

28

Comprende el archivo composer.json

29

Extendiendo composer.json, autocarga de clases y PSR-4

30

Crear mis propios Services Providers

31

Publicaci贸n de archivos

32

Uso de repositorios locales

33

Publicaci贸n de paquetes en packagist

No tienes acceso a esta clase

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

API de autenticaci贸n: laravel UI y laravel sanctum

6/33
Recursos

Aportes 56

Preguntas 7

Ordenar por:

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

o inicia sesi贸n.

Creo que falt贸 un pedazo al inicio del video, para instalar Sanctum debe hacerse con el siguiente c贸digo desde la terminal:

composer require laravel/sanctum

demasiados DEMASIADOSSS criterios sin explicar en este curso, perdido totalmente apesar de haber visto los anteriores de php y laravel, lo extra帽o es que cuando habla se le entiende lo que dice, se nota que tampoco es arrogante y su lenguaje y manera de explicar es muy amigable, que paso aqui platzi???

Se extra帽a al profesor Italo uu

Si est谩n utilizando PostMan deben de modificar el Header Accept para que solo de respuesta Postman acepte del tipo application/json.

Quedar铆a algo como:

Accept: application/json

La validaci贸n dentro de UserTokenController, deber铆a quedar as铆, 茅sto para que en caso de que el usuario no exista o la contrase帽a no es correcta, nos lance el mensaje de error.

if (!$user || !Hash::check($request->password, $user->password)) {
         throw ValidationException::withMessages([
               'email' => ['El email no existe o no coincide con nuestros datos.'],
	]);
}

el video esta cortado no esta la parte de laravel ui

Hay muchos errores empezando por la logica mal implementada en el Throw

Esto esta mal porque literlamente dice: Si el usuario no existe y si el password no coincide

 if (!$user && !Hash::check($request->password, $user->password) {

Lo correcto seria:

 if (!$user || !Hash::check($request->password, $user->password) {

Para crear el usuario pueden utilizar tinker

php artisan tinker

App\User::create(['name'=>'nombre','email'=>'[email protected]','password'=>Illuminate\Support\Facades\Hash::make('contrase帽a')];

Publico algunos cambios en mi UserTokenController que a mi me ha funcionado mejor:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\UserTokenRequest;
use Illuminate\Validation\ValidationException;

class UserTokenController extends Controller
{
    
    public function __invoke(UserTokenRequest $request)
    {
        $user = User::where('email', $request->email)->first();

        if ( !$user->exists() || !Hash::check($request->password, $user->password) ) {
            throw ValidationException::withMessages([
                'email' => 'El usuario no se encuentra o es incorrecto'
            ]);
        }

        return response()->json([
            'token' => $user->createToken($request->device_name)->plainTextToken
        ]);
    }
}

Vale, el video est谩 cortado y no se explic贸 lo de Laravel UI (Pero se explica en otros cursos) Laravel UI nos provee la autenticaci贸n en el caso que estemos trabajando sobre una aplicaci贸n que va a renderizar Laravel, no sobre una API, esto porque la API no contiene nada de l贸gica de frontend, todo es backend ^^

Les dejo la url del commit de esta clase:

https://github.com/RetaxMaster/platzi-api/commit/c2e0f1c7ff09b533b99892fae2eb453ff47ae83a

Creo que deber铆an de mejorar este curso, hay muchas cosas que se dejan al aire, existen cortes en el video, no se que paso con este curso si todos los anteriores a este con el profesor Italo Morales eran muy buenos鈥

Un pregunta profe

al usar throw ValidationException::withMessages([]

si falla a mi me manda a http://127.0.0.1:8000 no me salen los mensaje de la excepciones

que tengo que hacer me puede ayudar por favor

En el caso del if donde verifica si User existe o el hash coincide tuve que separarlo porque daba un error de que el user->password no encontraba la propiedad password, qued贸 de la siguiente manera:

if (!$user) {
  throw ValidationException::withMessages([
    'email' => 'El email no existe o no coincide con los datos',
  ]);            
}

if (!Hash::check($request->password, $user->password)) {
  throw ValidationException::withMessages([
    'email' => 'El email no existe o no coincide con los datos',
  ]);            
}

Para quienes ha tenido problemas no se olviden de poner en los archivos del test

<code> 
use App\User;
use Laravel\Sanctum\Sanctum;

Siento que esta todo mal explicado, muchas cosas

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

Actualmente estoy intentando realizar este curso pero pareciera que hubieran cortado clases por que aparece el controlador de categor铆a as铆 como por arte de magia

Este curso necesita una nueva edici贸n, est谩 como mal editado.

Les dejo una manera optima de hacer un login o creaci贸n de token en laravel +8

public function __invoke(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
            'device_name' => 'required'
        ]);
         throw_if(!Auth::guard('web')->attempt($request->only('email','password')), ValidationException::withMessages([
             'email' => 'Credenciales incorrectas'
         ]));

         return response([
             'token'=> Auth::guard('web')->user()->createToken($request->device_name)->plainTextToken
         ])->setStatusCode(Response::HTTP_OK);

    }

Y para crear el usuario r谩pido, usen esta forma en el archivo DatabaseSeeder.php

User::create([
            'name' => 'Admin',
            'email' => '[email protected]',
            'password' => '$2a$10$7oMxkBuQ0PpbVxpJl0ufNerj0TTuZmRxrD76LlyKCaMCh8bpZqVS2',   //admin
        ]);

Asi debe ir el condicional en el UserTokenController:

if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['Las credenciales son incorrectas.'],
            ]);
        }

        return response()->json([
            'token' => $user->createToken($request->device_name)->plainTextToken
        ]); 

Creo que tambien deberia de mstrar todo el codigo en pantalla porque hay muchos namespace que no se ve donde los grega鈥

En mi opini贸n, este profesor deja muchas cosas en el aire y sin explicar, espero cambien de profesor para futuros cursos de laravel porque con Sergio Ojeda no me entero鈥

En la parte del test min 3:20 es necesario agregar la clase Sanctum al principio. El IDE del profesor la agrega autom谩ticamente.
Por otra parte, Sanctum tiene dos formas de autenticar:

  1. Con tokens tal como lo explico el profesor. Esto es para cuando API sirve a multiples apps o se integra con otros sistemas
  2. Usando cookies. Cuando tienes un frontend solamente. Si usas este m茅todo no es necesario generar los tokens tal como se vio en este video.
<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Http\Requests\UserTokenRequest;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Hash;

class UserTokenController extends Controller
{
    public function __invoke(UserTokenRequest $request)
    {
        /** @var User $user */
        $user = User::where('email', $request->input('email'))->first();

        if (!$user) {
            throw ValidationException::withMessages([
                'email' => 'El email no existe',
                ]);
        }

        if (!Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'password' => 'Contrase帽a incorrecta',
            ]);
        }

        $token = $user->createToken($request->device_name)->plainTextToken;

        return response()->json([
            'token' => $token,
        ]);
    }
}

Estoy tratando de adaptar todo lo que explica aqu铆 a Laravel 10... est谩 dif铆cil. Platzi, actualicen esto! es realmente frustrante!

Buscar茅 otro curso de laravel, no entend铆 nada de homestead, los archivos creo que los instal茅 donde no era. Estoy usando windows y nada, 鈥渘o specific file found鈥 no me funciona nada. Con 茅sta clase termin茅 de perderme.

Laravel 10 ya viene configurado con sanctum

A lo que va del curso pienso que se deberia actualizar a laravel 9 , lo que hace que el profe se quede corto en su explicacion y no es culpa de el, sino de que ya se han actualizado procesos

En versiones m谩s recientes podr铆an realizarlo de esta forma

    public function test_index()
    {
        $user = User::factory()->create();

        Product::factory(5)->create();

        $this
            ->actingAs($user)
            ->get('/api/products')
            ->assertSuccessful()
            ->assertHeader('content-type', 'application/json')
            ->assertJsonCount(5);
    }

les dejare unos datos para se les faciliten las cosas en laravel 9, si ven el se loguea con usuarios y no emos visto nada de ellos, entonces debemos agregar el seeder, les dejo el
DatabaseSeeder.php

    public function run()
    {
        $seeds = array_merge(
            [
                ProductSeeder::class,
                UserSeeder::class,
            ]
        );

        $this->call($seeds);
    }

luego creamos el UserSeeder con este comando

php artisan make:seed UserSeeder

y a UserSeeder.php le agregamos esto:

    public function run()
    {
        User::factory(10)->create();
    }

para finalizar, el factory se user ya existe, solo demos cambiar el string que aparece en el campo de contrase帽a, con una contrase帽a encryptada, entonces el UserFactory.php se ve asi

    public function definition()
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => bcrypt('password'),
            'remember_token' => Str::random(10),
        ];
    }
    public function unverified()
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }

la contrase帽a de todos los usuarios que creemos sera la palabra 鈥減assword鈥,
ahora debemos correr los seeder conm este comando

php artisan db:seed

y si quieren hacer mejor un refresh y los seed seria asi

php artisan migrate:refresh --seed

ahora ya podemos copiar cualquier coreo de los usuarios de la base de datos y colocar como contrasena a todos 鈥減assword鈥 y podran probar desde postman con ellos.
parta terminar, tambien les dejo el archivo de UserTokenController.php

    public function __invoke(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
            'device_name' => 'required',
        ]);
        $user = User::whereEmail($request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['estas credenciales no existen o no coinciden con nuestros datos.'],
            ]);
        }

        $token = $user->createToken($request->token_name);

        return response()->json([
            'token' => $token->plainTextToken
        ]);
    }

cabe mencionar que podriamos haber creado un login request y validan la informacion ahi y no en el metodo invoke de la clase UserTokenController

Single Action Controllers

Si quer茅s definir un controlador que s贸lo maneje una acci贸n simple, pod茅s agregar el m茅todo simple __invoke al controlador:

<?php
 
namespace App\Http\Controllers;
 
use App\User;
use App\Http\Controllers\Controller;
 
class ShowProfile extends Controller
{
    public function __invoke($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

Cuando registres rutas con controladores de acciones simples, no necesitas especificar un m茅todo:

Route::get('user/{id}', 'ShowProfile');

Pod茅s generar un controlador invokable usando la opci贸n --invokable del comando Artisan make:controller:

php artisan make:controller ShowProfile --invokable

Una forma f谩cil para assert que los Header del response sean de tipo '鈥榗ontent-type鈥, 鈥榓pplication/json鈥 es hacerlo desde el controlador enviado la respuesta de esta manera:

 public function store(Request $request)
    {        
       return response()->json(Product::create($request->all()));   
  }

La otra forma mas elaborada es crear un Resource
"ProductResource"

el profe explica muy bien, pero creo que a ustedes les faltara importar: use Illuminate\Validation\ValidationException; y esta parte es con || en lugar de &&
if(!$user || !Hash::check($request->password, $user->password) ){
throw ValidationException::withMessages([
鈥榚mail鈥 => 鈥榚mail or password doesn鈥檛 match with our records鈥
]);
}

Tambien creen un UserSeeder que llame el userFactory, para que puedan crear con postman

El cap铆tulo API de autenticaci贸n no dice nada sobre Laravel UI, salta directamente a Sanctum para APIs.

De hecho, creo que tambi茅n se est谩n mezclando conceptos. En las APIs no hay uso de cookies, solo de tokens (ejemplo JWT, OAuth鈥). Las cookies y sesiones se usan en la parte web (rutas en web.php) con un navegador asociado a las peticiones.

驴Qu茅 opin谩is?.

En el curso de OAuth2 pod茅is ver m谩s al respecto.

Saludos!.

php artisan make:controller UserTokenController --invokable

Con este comando se puede crear el controller con el metodo __invoke directamente

En laravel 8, Sanctum ya viene instalado por defecto

Considerando que en el curso de omiten varias explicaciones una de ellas es la creaci贸n de los usuarios 鈥
Pueden crear el seeder de usuario ejecutando el comando

php artisan make:seeder UserSeeder

y agregar la siguiente l铆nea en el seeder creado

factory(\App\User::class, 20)->create();

y si necesitan ejecutar solo ese seeder lo hacen con

php artisan db:seed --class=UserSeeder

Saludos! no pierdan el animo!

Para probar el funcionamiento del endpoint es necesario tener un usuario registrado, lo puedes ingresar en el registro desde el formulario web (si instalaste laravel ui) o con PHP Tinker.

Dejo el comando por si acaso tienen alguna falla.

php artisan vendor:publish --provider=鈥淟aravel\Sanctum\SanctumServiceProvider鈥

Si no te reconoce la clase Sanctum en el controlador, agega esta linea arriba.

use Laravel\Sanctum\Sanctum;

Excelente gracias.

Para las personas que quieren ver el tema de Laravel UI, les dejo este tutorial en espa帽ol sobre Laravel UI

Laravel UI

EnsureFrontendRequestsAreStateful::class

es necesario que la ruta "/sanctum/token valla a esa url?

hice un controllador para crear un usuario sepa si esta bien, jajaj si les sirve ah铆 esta, solamente asignale una ruta

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validator = $request->validate([
            'email' => 'required|email',
            'name' => 'required',
            'password' => 'required',
        ]);

     
        $newUser = User::create(['name' => $request->name,'email'=>$request->email,'password'=>Hash::make($request->password)]);

        return response()->json($newUser);
    }
}

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs. Sanctum allows each user of your application to generate multiple API tokens for their account. These tokens may be granted abilities / scopes which specify which actions the tokens are allowed to perform.
Fuente: https://laravel.com/docs/8.x/sanctum

https://laravel.com/docs/7.x/sanctum

Mas informacion acerca de Sanctum

La validaci贸n de que exista el usuario y de que la contrase帽a sea correcta usa los operadores && en lugar de || ya que, como est谩 en el video, la contrase帽a aun si es incorrecta pero el usuario si existe se generar谩 el token.

if(!$user || !Hash::check($request->password, $user->password){
// C贸digo
}

No seria mejor hacerlo con passport?

Al comienzo del video antes de publicar los archivos puedes instalar ambos paquetes con un solo comando:

composer require laravel/sanctum laravel/ui

Lo que yo hice fue validar que ambos fueran verdaderos, ya que debemos asegurar que el usuario exista y que las contrase帽as coincidan, puse el throw en el else.

if( $user && Hash::check($request->password, $user->password) ){
            return response()->json([
                'token' => $user->createToken($request->device_name)->plainTextToken
            ]);
        } else {
            throw ValidationException::withMessages([
               'email' => 'El email no existe o no coincide'
            ]);
        }

No se si sea la mejor manera de hacerlo.

Mi soluci贸n:

if( isset($user) ){
	if( !Hash::check( $request->password, $user->password ) ){
		throw ValidationException::withMessages([
			'password' => 'Acceso incorrecto.'
		]);
	}
}else{
	throw ValidationException::withMessages([
		'email' => 'El email no existe o es invalido'
	]);
}

return response()->json([
	'token' => $user->createToken( $request->device_name )->plainTextToken
]);

Para el metodo de autenticacion usen esto
use Illuminate\Support\Facades\Auth;

$this->validateLogin($request);

    if (Auth::attempt($request->only('email', 'password'))) {
      return response()->json([
        'token' => $request->user()->createToken($request->name)->plainTextToken,
        'message' => 'Success'
      ]);
    }

    return response()->json([
      'message' => 'Unauthorized'
    ], 401);
  }

    public function validatelogin(Request $request)
    {
        return $request->validate([
            'email' => 'required|email',
            'password' => 'required',
            'name' => 'required'
        ]);
    }```

En mi caso tuve que refactorizar el codigo para proteger la ruta, con laravel 8 la declaracion de la ruta

Route::apiResource('professions', 'ProductController')->middleware('auth:sanctum');

me daba un error tuve que escribirlo asi:

Route::apiResource('professions', ProductController::class)->middleware('auth:sanctum');

Buen video

Con Laravel 8 cuando uso la api con una contrase帽a errada la respuesta es una redirecci贸n 302. 驴Alguna sugerencia?