Laravel Sanctum tokens() undefined - laravel-8

i'm new to laravel and trying to build an api for a login using sanctum.
I followed documentation, and a few tutorials but i've encountered an error where the token function is not accessible by my user class even when using HasApiToken.
here is my user model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
'alt_id',
'country_id',
'birth'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'type',
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function country()
{
return $this->hasOne(Country::class);
}
}
[this is the error message][1]
[1]: https://i.stack.imgur.com/QzGK9.png
I also already checked the route in config/auth.php and it is App\Models\User::class

I've solved that problem by adding $user->tokens()->delete(); into my AuthController#logout,
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
public function logout(User $user){
$user->tokens()->delete();
return [
'message' => 'Logged out'
];
}
}
And User model looks like this.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
//some code
];
protected $hidden = [
//some code
];
protected $casts = [
//some code
];
}

Related

in laravel hasMany() relation is working but belongsTO not working

i have two tables 1: users 2: roles
as for migration of users table like this
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('role_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('username');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('profile_image')->default('user.png');
$table->text('about')->nullable();;
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
`
as for roles table migration
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('role_title');
$table->string('role_slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
};
`
User mode
`
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Models\Role;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public function role(){
return $this->belongsTo(Role::class);
}
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
`
Role model
`
<?php
namespace App\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Role extends Model
{
use HasFactory;
public function users(){
return $this->hasMany(User::class);
}
}
`
so i have tried
App\Models\Role::find(1)->users;
so it is returning
`
Illuminate\Database\Eloquent\Collection {#4831
all: [
App\Models\User {#4829
id: 2,
role_id: 1,
name: "zahid",
username: "admin",
email: "admin#gmail.com",
email_verified_at: null,
#password: "$2y$10$6Up.B4.0gytPsVWOT/f0eeG4yk.u466FDRNf34yYZwxbwyKJh8o8u",
updated_at: null,
},
],
}
`
and
App\Models\User::find(2)->roles;
it is returning null
please tell me where is my fault in code why my belogsTo not working. i want for one use lke jone or nike contains only one role lke author or admin or writer etc. but one role lke admin or it could be contain multiple users lke multiple user can be admin or author.
is in my logic any fault or in code above.
plz help me. and thank for advaced for all helpfull code loves.

Issue With Laravel 8 Auth Email Verification

I'm Using Laravel 8.x And i'm trying to make login/register With Email verification
I followed Some Tutorials,Blogs but didn't get desired output
I want:-
Whenever User Register themselve An Verification Email must send to there email
(Email Is Sent but not able to verify by that url so i follow some laracast blog by that i'm able to verify by that verification url)
but the issue is if i didn't verified my self i'm still able to login into my application
Here Is Codes
HomeController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(['auth','verified']);
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('home');
}
}
Register Controller
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/*
','--------------------------------------------------------------------------
',' Register Controller
','--------------------------------------------------------------------------
','
',' This controller handles the registration of new users as well as their
',' validation and creation. By default this controller uses a trait to
',' provide this functionality without requiring any additional code.
','
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'contact' => ['required','min:10'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required','string','min:8','confirmed','regex:/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{6,}$/'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'contact' => $data['contact'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
Veification Controller
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Verified;
use Illuminate\Auth\Access\AuthorizationException;
use App\Models\User;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
// $this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
public function verify(Request $request)
{
// if ($request->route('id') != $request->user()->getKey()) {
// throw new AuthorizationException;
// }
$user = User::find($request->route('id'));
auth()->login($user);
if ($request->user()->hasVerifiedEmail()) {
return redirect($this->redirectPath());
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect($this->redirectPath())->with('verified', true);
}
}
Route
Auth::routes(['verify' => true]);
Route::group(['prefix'=>'user', 'middleware' => 'auth'],function(){});

Auth::attempt return False

My problem with Auth::attempt return False
I'm moving from codeignter to laravel 8
I start with new laravel project and connected with my DB
Ihis is my controller (change password to to save hash password in DB)
public function loginCheck(Request $request)
{
dd(Auth::attempt(['email'=>$request->email,'password'=>$request->password])); // return false
$credentials = $request->only('email', 'password');
if (Auth::attempt(['email'=>$request->email,'password'=>$request->password])) {
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
return back()->withErrors(['email' => 'The provided credentials do not match our records.']);
}
public function changePasswordAction(Request $request){
$user=User::where('u_username',$request->username)->orWhere('email',$request->email)->first();
// dd($user);
//new pass
$user->password = Hash::make('123456');
$user->save();
}
this my user model
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $table = 'user';
protected $primaryKey = 'u_id';
public $timestamps = true;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'u_fullname',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
// 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
}
Email filed in DB:
email varchar(255) utf8_general_ci
Password filed in DB:
password varchar(255) utf8_general_ci
i have find solution i just remove this funcation from user model
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
its was made a duplication in Hash code

notification system in Laravel 8

I am working on a laravel app where i have a user(organizer) who post an event ,and other users can comment on this event .
I am trying to make notifications system in laravel 8 between the organizer and the users when commenting on these event !
but i get this error (Call to a member function notify() on null).
This is my class :
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewCommentPosted extends Notification
{
use Queueable;
protected $user;
protected $event;
public function __construct($user, $event)
{
$this->user = $user;
$this->event = $event;
}
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'user' => $this->user->name,
'eventTitle' => $this->event->title,
'eventId' => $this->event->id
];
}
This is storefunction() in my controller :
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Comment;
use App\Notifications\NewCommentPosted;
use Illuminate\Http\Request;
class CommentController extends Controller
{
public function store(Event $event)
{
request()->validate([
'content' => 'required|min:5'
]);
$comment = new Comment();
$comment->content = request('content');
$comment->user_id = auth()->user()->id;
$event->comments()->save($comment);
$event->user->notify(new NewCommentPosted(auth()->user(), $event));
return redirect()->route('events.show', [$event->id, $event->title]);
}
Any help please !!?

Two middleware for only one Function in laravel

I can use only one middleware at a time..inside a constructor..I want to use if else condition inside constructor or two middleware.
I can use only one middleware inside constructor & if else condition also not working
I want only one function work or use according to middleware.I have two seprate table for authentication
Following middleware pointing to diffrent table
$this->middleware('auth:admin') - admins
$this->middleware('auth')- user
Example are follows
If else
class HRJob extends Controller
{
public function __construct()
{
if(Auth::guard('admin'))
{
$this->middleware('auth:admin');
}
else
{
$this->middleware('auth');
}
}
public function userdetails()
{
dd(Auth::user());
}
}
Two middleware
class HRJob extends Controller
{
public function __construct()
{
$this->middleware('auth:admin');
$this->middleware('auth');
}
public function userdetails()
{
dd(Auth::user());
}
}
You can try like this in the controller
class UserController extends Controller
{
/**
* Instantiate a new UserController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => [
'fooAction',
'barAction',
]]);
$this->middleware('subscribed', ['except' => [
'fooAction',
'barAction',
]]);
}
}
Also you can use Middleware groups
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
'auth:api',
],
];
More: https://laravel.com/docs/master/middleware