retrive relation table in login request with laravel breeze - laravel

Hello I want to include my relation table roles when I login. I used Laravel Breeze for authentication.
Models/User.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 string[]
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
//old
public function bookmarks(){
return $this->hasMany('App\Model\Post','post_bookmarks','user_id','post_id')->get();
}
public function roles(){
return $this->belongsTo('App\Models\Roles','roles','role_id','id');
}
}
AuthenticatedSessionController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
LoginRequest.php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*
* #return string
*/
public function throttleKey()
{
return Str::lower($this->input('email')).'|'.$this->ip();
}
}
I have used Laravel-breeze for the authentication. It's all working fine but I want to add Role name also when user gets login. As you can see I have also used relationship but I'm confused where can I write the code to get my relation table. This is my code, Can anyone please tell me how can I do?
For Ex.
login email: poojan#gmail.com
role_id = 1
in roles table
id: 1, role_name = "Wholseler"
So when I logged in currently I'm getting user data, But I want roles table data too.
Thanks in Advance

you can use attribute in your user model
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->roles->first()->role_name ?? 'N/A';
}
using the above code you will get the role_name attribute in the user instance
if you want roles data into relations of user data try this in user model
protected $with = ['roles'];

Related

Wrong on login and restet pasword on LARAVEL 9

enter image description here
Login is failed, the credencials email and password, is correct, but laravel dont acces to dashboard
The password reset is worng to, the email is correct and i try chance of credentials on myphpadmin but dont entry.
this is my code
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
If you're mass assignment while attempting authentication make sure the form requested keys must same as Model's $fillable keys.
then try this:
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$credentials = $request->validated();
if (Auth::attempt($credentials)) {
return redirect()->intended(RouteServiceProvider::HOME);
}
return back()->with('message', 'The given credentials are not matched');
}
if you're working with multi guards, try this:
public function store(LoginRequest $request)
{
$credentials = $request->validated();
if (Auth::guard('web')->attempt($credentials)) {
return redirect()->intended(RouteServiceProvider::HOME);
}
return back()->with('message', 'The given credentials are not matched');
}
I have tested this example code from your and my implementation
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Hash;
use Session;
use App\Models\User;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return redirect()->intended('dashboard')
->withSuccess('Signed in');
}
return redirect("login")->withSuccess('Login details are not valid');
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Session::flush();
Auth::logout();
return redirect('/');
}
/**
* Registration page.
*
*/
public function registration()
{
return view('auth.registration');
}
/**
* Store new user request handler
*
*/
public function storeUser(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
]);
$data = $request->all();
$check = $this->create($data);
return redirect("dashboard")->withSuccess('have signed-in');
}
/**
* Store new user
*
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password'])
]);
}
/**
* Dashboard for user
*
*/
public function dash()
{
if(Auth::check()){
return view('dashboard');
}
return redirect("login")->withSuccess('are not allowed to access');
}
}
Please check from your project and check flash messages if password was wrong check password hashing correctly

How to send only one event in Pusher channel and then for database notification store for all users

I've created a broadcast channel App.Models.Admin.Notify where all the admin users will be subscribed to this channel by default.
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.Models.Admin.Notify', function ($m) {
return !is_null($m) && $m->getMorphClass() === 'admin';
});
And this is the Notifications/Base.php where i've set ['database', 'broadcast', OneSignal::class] as notification channels
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use NotificationChannels\OneSignal\OneSignalMessage;
use App\Channels\OneSignal;
abstract class Base extends Notification implements ShouldBroadcast, ShouldQueue
{
use Queueable;
public $model;
protected string $icon;
public function __construct(mixed $m = null)
{
$this->model = $m;
}
/**
* Get notify id
*
* #return string
*/
protected function getNotifyId(): string
{
return $this->id;
}
/**
* Get icon path
*
* #return string
*/
protected function getIcon(): string
{
return asset('favicon.ico');
}
/**
* Get notification link
*
* #return string
*/
protected function getLink(): string
{
return asset('favicon.ico');
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return \App\Channels\PusherBeams\PusherMessage
*/
public function via($notifiable)
{
return [
'database',
'broadcast',
OneSignal::class
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return array_merge(
[
'link' => $this->getLink(),
'icon' => $this->getIcon(),
],
$this->getData($notifiable)
);
}
/**
* Get data of message.
*
* #param mixed $notifiable
* #return array
*/
protected function getData($notifiable)
{
return [
'title' => 'hello',
'body' => 'world'
];
}
/**
* Create onesignal message of Web
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toWeb($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setUrl($data['link']);
}
/**
* Create onesignal message of Android
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toAndroid($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setData('url', str_replace('https://', 'gamepts://', $data['link']));
}
/**
* Websocket message
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\BroadcastMessage
*/
public function toBroadcast($notifiable)
{
return (new BroadcastMessage($this->toArray($notifiable)))->onQueue('pusher');
}
}
So this is the basic setup for my Notifications and broadcasting.
I've a job which runs every minutes and if any reports are found then it should send the notification if any reports are found.
<?php
namespace App\Console\Commands;
use Carbon\Carbon;
use App\Models\MerchantDeposit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;
class CheckCashIn extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'check:cashin';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Check expiration of cash in orders';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$setting = app(\App\Settings\CurrencySetting::class)->currency;
$expired_limit = app(\App\Settings\AdminSetting::class)->expired_payin_limit_notify;
$reports = [];
foreach ($setting as $currency => $s) {
$expired_minutes = $s['expired_minutes'];
$k = MerchantDeposit::where('status', MerchantDeposit::STATUS['PENDING'])
->where('currency', $currency)
->where('created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->update(['status' => MerchantDeposit::STATUS['EXPIRED']]);
$o = MerchantDeposit::where('merchant_deposits.status', MerchantDeposit::STATUS['EXPIRED'])
->join('reseller_bank_cards', 'reseller_bank_cards.id', 'merchant_deposits.reseller_bank_card_id')
->join('resellers', 'resellers.id', 'reseller_bank_cards.reseller_id')
->where('merchant_deposits.currency', $currency)
->where('merchant_deposits.created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->having(DB::raw('COUNT(resellers.name)'), '>=', $expired_limit)
->select('resellers.name', DB::raw('COUNT(resellers.name) AS total_expired'), DB::raw('TRUNCATE(SUM(merchant_deposits.amount), 2) AS total_amount'), 'merchant_deposits.currency')
->groupBy('resellers.name', 'merchant_deposits.currency')
->get();
if (!empty($o->toArray()) && $k > 0) {
$reports[$currency] = [];
foreach ($o as $k => $v) {
$reports[$currency][$v->name] = $v->total_expired;
$reports[$currency]['Total Amount'] = $v->total_amount;
}
}
}
if (!empty($reports)) {
Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports));
}
}
}
And in Model/Admin.php i've set receivesBroadcastNotificationsOn to update the channel name for the broadcast to send into pusher.
<?php
namespace App\Models;
use App\Trait\HasJWTSubject;
use App\Trait\UserLogsActivity;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;
use Illuminate\Notifications\Notifiable;
use Laravel\Lumen\Auth\Authorizable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Spatie\Permission\Traits\HasRoles;
/**
* Model of admin
* #package Models
*/
class Admin extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable, HasFactory, HasJWTSubject;
use UserLogsActivity;
use Notifiable;
use HasRoles;
protected $fillable = [
'name',
'username',
'password',
'status',
'timezone'
];
protected $hidden = [
'password',
];
protected $casts = [
'status' => 'boolean',
];
public const STATUS = [
'DISABLED' => false,
'ACTIVE' => true,
];
public function getIsSuperAdminAttribute()
{
return $this->hasRole('Super Admin');
}
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
public function devices()
{
return $this->morphMany(Device::class, 'user');
}
public function receivesBroadcastNotificationsOn()
{
return 'App.Models.Admin.Notify';
}
}
When the notification is triggered from Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it will send broadcast notification multiple times to same broadcast channel as shown in the screenshot below
From Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it is fine to save the notification records for all the admin in database notification but for pusher i want the notification event to sent only once instead of sending multiple times ie 'x' number of admins.
Lets say i have 100 admin users then now pusher will send the event to same channel 100 times. So i want to minimize the pusher event to just 1 channel where all the admin users subscribed can receive the notification but it should also save the records for 100 users in the notification table of database.

Email verification in laravel when using api routes

I have created laravel api for angular application to register user this is the Registration code and it is working but i want to verify user email after user is registered. I have used laravel default laravel verification in web but i don't have idea of using it in api.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Auth\Events\Verified;
use Validator;
class AuthController extends Controller
{
public function __construct() {
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Get a JWT via given credentials.
*
* #return \Illuminate\Http\JsonResponse
*/
public function login(Request $request){
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
if (! $token = auth()->attempt($validator->validated())) {
return response()->json(['error_message' => 'Invalid Credentials'], 401);
}
return $this->createNewToken($token);
}
/**
* Register a User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function register(Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required|string|between:2,100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:6',
]);
if($validator->fails()){
return response()->json($validator->errors(), 422);
}
$user = User::create(array_merge(
$validator->validated(),
['password' => bcrypt($request->password)]
));
return response()->json([
'message' => 'User successfully registered',
'user' => $user
], 201);
}
/**
* Log the user out (Invalidate the token).
*
* #return \Illuminate\Http\JsonResponse
*/
public function logout() {
auth()->logout();
return response()->json(['message' => 'User successfully signed out']);
}
/**
* Refresh a token.
*
* #return \Illuminate\Http\JsonResponse
*/
public function refresh() {
return $this->createNewToken(auth()->refresh());
}
/**
* Get the authenticated User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function userProfile() {
return response()->json(auth()->user());
}
/**
* Get the token array structure.
*
* #param string $token
*
* #return \Illuminate\Http\JsonResponse
*/
protected function createNewToken($token){
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60,
'user' => auth()->user()
]);
}
}
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;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject, MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
'email_verified_at'
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier() {
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims() {
return [];
}
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Please give some solution, Thanks
Option1
So one way i handle this is by checking the email_verified_at column on your user.
when a user logs in check if email_verified_at exists.
I also have a separate table called user_verification_tokens which contain a userID, token, and tokenExpiryDate
if it doesn't exist you can enforce verification by not logging them in until they verify their email. This could send a email to the user.
When the email gets generated a UUID gets inserted into the token column in the user_verification_tokens and sent through to the email. When the user clicks on the email and it checks on an unauthenticated route if that token exists then updates the email_verified_at column.
Option2
Generate a OTP that that gets sent to the email
User manually enters OTP
Verify UserID + OTP exists
Update email_verified_at

Laravel 8 Multi Auth with Jetstream livewire

im trying to setup a multi auth system in laravel 8 with jetstream livewire in my ecomm project (one login page for admins(/admin/login) and another for users(/login))
i have followed a tutorial and everything is ok expect when i login to user from /login page i can access /admin/dashboard with that user and with admin its fine and cant access user /dashboard
routes\web.php:
Route::get('/', function () {
return view('welcome');
});
Route::group(['prefix'=>'admin','middleware'=>['admin:admin']],function(){
Route::get('/login', [AdminController::class, 'loginForm']);
Route::post('/login', [AdminController::class, 'store'])->name('admin.login');
Route::get('/logout', [AdminController::class, 'Logout'])->name('admin.logout');
});
Route::middleware(['auth:sanctum,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
Route::middleware(['auth:sanctum,web', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
Models\Admin.php:
<?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\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
class Admin extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'profile_photo_url',
];
}
Controllers\AdminController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Routing\Pipeline;
use App\Actions\Fortify\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable;
use App\Http\Responses\LoginResponse;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\LogoutResponse;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Http\Requests\LoginRequest;
use Auth;
class AdminController extends Controller
{
/**
* The guard implementation.
*
* #var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* #param \Illuminate\Contracts\Auth\StatefulGuard
* #return void
*/
public function __construct(StatefulGuard $guard, Request $request)
{
$this->guard = $guard;
}
public function loginForm(){
return view('admin.login',['guard'=>'admin']);
}
public function Logout(){
Auth::logout();
return Redirect()->url('admin/login')->with('success', 'Logged Out');
}
/**
* Show the login view.
*
* #param \Illuminate\Http\Request $request
* #return \Laravel\Fortify\Contracts\LoginViewResponse
*/
public function create(Request $request): LoginViewResponse
{
return app(LoginViewResponse::class);
}
/**
* Attempt to authenticate a new session.
*
* #param \Laravel\Fortify\Http\Requests\LoginRequest $request
* #return mixed
*/
public function store(LoginRequest $request)
{
return $this->loginPipeline($request)->then(function ($request) {
return app(LoginResponse::class);
});
}
/**
* Get the authentication pipeline instance.
*
* #param \Laravel\Fortify\Http\Requests\LoginRequest $request
* #return \Illuminate\Pipeline\Pipeline
*/
protected function loginPipeline(LoginRequest $request)
{
if (Fortify::$authenticateThroughCallback) {
return (new Pipeline(app()))->send($request)->through(array_filter(
call_user_func(Fortify::$authenticateThroughCallback, $request)
));
}
if (is_array(config('fortify.pipelines.login'))) {
return (new Pipeline(app()))->send($request)->through(array_filter(
config('fortify.pipelines.login')
));
}
return (new Pipeline(app()))->send($request)->through(array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]));
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Laravel\Fortify\Contracts\LogoutResponse
*/
public function destroy(Request $request): LogoutResponse
{
$this->guard->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return app(LogoutResponse::class);
}
}
Responses\LoginResponse.php:
<?php
namespace App\Http\Responses;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
class LoginResponse implements LoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* #param \Illuminate\Http\Request $request
* #return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended('admin/dashboard');
}
}
i also created a copy of StatefulGuard in App\Guards\AdminStatefulGuard.php following that tutorial but never used it.
Problem fixed by adding this code to my admin controllers.
public function __construct()
{
$this->middleware(['auth:admin,admin', 'verified']);
}
and also replacing this in web route:
Route::middleware(['auth:sanctum,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
with this:
Route::middleware(['auth:admin,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
Try this on Admin middleware
public function handle(Request $request, Closure $next, $guard)
{
if (Auth::guard($guard)->check()) {
return redirect('/admin/dashboard');
}
if(Auth::guard('web')->check()) {
return redirect('/dashboard');
}
return $next($request);
}
and on RedirectIfAuthenticated middleware:
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
}
if(Auth::guard('admin')->check()) {
return redirect('admin/dashboard');
}
return $next($request);
}

I get BadMethodCallException Call to undefined method App\Models\User::identifiableAttribute()

I get this error after clicking 'New Post' button the frontend of the app:
Posts view
Line from my log file:
[2020-09-27 14:41:03] local.ERROR: Call to undefined method App\Models\User::identifiableAttribute() {"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method App\Models\User::identifiableAttribute() at C:\xampp\htdocs\backpack-demo\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php:50)
I am using Laravel 7 + Backpack CRDU generator
Posts Controller:
<?php
namespace App\Http\Controllers;
use App\Events\NewPost;
use App\Http\Requests\PostStoreRequest;
use App\Jobs\SyncMedia;
use App\Mail\ReviewPost;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class PostController extends Controller
{
/**
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request)
{
$posts = Post::all();
return view('post.index', compact('posts'));
}
/**
* #param \App\Http\Requests\PostStoreRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(PostStoreRequest $request)
{
$post = Post::create($request->validated());
Mail::to($post->author->email)->send(new ReviewPost($post));
SyncMedia::dispatch($post);
event(new NewPost($post));
$request->session()->flash('post.title', $post->title);
return redirect()->route('post.index');
}
}
Posts Model:
class Post extends Model
{
use CrudTrait;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'title',
'content',
'published_at',
'author_id',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'id' => 'integer',
'author_id' => 'integer',
];
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = [
'published_at',
];
public static function create(array $validated)
{
}
public function author()
{
return $this->belongsTo(User::class);
}
}
User model:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', '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',
];
}
your have forgotten to use 'CrudTrait' in your User Model:
use Backpack\CRUD\app\Models\Traits\CrudTrait;
class User extends Authenticatable
{
use Notifiable,CrudTrait
.......
}

Resources