I'm building an app that has pricing. I would want to assign some special price to some specific users.
In the model that has the price, I'm trying to use an accessor to "tweak" the price like so:
public function getPriceAttribute($price)
{
dd(auth()->user()); //this returns null
if (auth()->check()) {
$user = auth()->user();
return $user->aDefinedRelationship()->first()->price;
}
return $price;
}
However auth()->user() always returns null.
I'm using the traditional Laravel authentication, no external library.
Please is there something I'm not doing right?
Any help would be appreciated.
More information:
auth.php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Api\V1\Models\User::class,
],
],
];
ThePriceModel.php
namespace App\Api\V1\Models;
use Illuminate\Database\Eloquent\Model;
class ThePriceModel extends Model
{
protected $table = 'prices';
protected $fillable = ['code', 'price'];
public function getPriceAttribute($price)
{
dd(auth()->user()); //this returns null
if (auth()->check()) {
$user = auth()->user();
return $user->aDefinedRelationship()->first()->price;
}
return $price;
}
}
After every other thing failed, I resorted to using a global config variable.
in config/constants.php:
return [
...
'user' => []
];
somewhere in my controller:
config()->set('constants.user', auth()->user());
Then in the model:
...
public function getPriceAttribute($price)
{
$user = config()->get('constants.user');
...
}
I suppose you were using API and this is why it didn't work. You could check for the user using this. You need to check API guard.
$user = \Auth::user() ?? \Auth::guard("api")->user();
Related
i'm try to using multi auth using Admin Guard and implement with Spatie, after login succes using the Admin Guard, then access the Group Middleware but i got an error 403 USER IS NOT LOGGED IN.
this is my code :
Admin Model :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class Administration extends Authenticable
{
use HasFactory, Notifiable, HasRoles;
protected $guard_name = 'admins';
protected $fillable = [
'name', 'email', 'username', 'password', 'photo'
];
protected $hidden = ['password'];
}
LoginController :
public function __construct()
{
$this->middleware('guest:admins')->except('logout');
}
public function authenticated(Request $request, $user)
{
if ($user->hasRole('admin')) {
return redirect()->route('bank.master-bank.index');
} else if ($user->hasRole('finance')) {
return redirect()->route('bank.master-bank.index');
} else if ($user->hasRole('supervisor')) {
return redirect()->route('bank.master-bank.index');
}
return redirect('login');
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (auth()->guard('admins')->attempt($request->only('email', 'password'))) {
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return redirect()->intended('/bank/master-bank');
} else {
$this->incrementLoginAttempts($request);
return redirect()
->back()
->withInput()
->withErrors(["Incorrect user login details!"]);
}
}
Auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'admins' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Administration::class,
],
],
Route Web.php
Route::group(['middleware' => 'auth:admins'], function () {
Route::group(['middleware' => ['role:admin']], function () {
Route::group(['prefix' => 'user', 'as' => 'user.'], function () {
Route::get('/', [UserAdminController::class, 'user_panel'])->name('user_panel');
Route::get('/role-user', [UserAdminController::class, 'role_panel'])
Route::get('/detail_user/{id}', [UserAdminController::class, 'detail_user'])
Route::resource('/verif-user', VerifUserController::class);
});
});
});
when access the Route::group(['middleware' => ['role:admin']], function () { i got error 403
USER IS NOT LOGGED IN.
Check you haven't define your middleware role and you are using it here.
So i changed config/auth.php to change default auth table from user to accounts like this :
'defaults' => [
'guard' => 'web',
'passwords' => 'accounts',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'accounts',
],
'api' => [
'driver' => 'token',
'provider' => 'accounts',
'hash' => false,
],
],
'providers' => [
'accounts' => [
'driver' => 'eloquent',
'model' => App\Akun::class,
],
],
i have changed App\Akun Model configuration same as App\User Model :
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Akun extends Authenticatable
{
use HasFactory;
protected $table = 'accounts';
protected $fillable = [
'nip',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
And My Login system is working too. It can return back if the NIP or Password wrong and give error message too. Here my login code:
function checklogin(Request $request){
$this->validate($request,[
'nip' => 'required',
'password' => 'required'
]);
$akun_data = array(
'nip' => $request->get('nip'),
'password' => $request->get('password')
);
if(Auth::attempt($akun_data)){
return redirect('login/successlogin');
}else{
return back()->with('pesan','NIP atau Password salah');
}
}
it was working and return correctly to login/successlogin and run the code in there. But when i tried to add middleware('auth') to the route of login/succeslogin , it'll always return back to login page even when i gave the correct nip and password
Route::get('/login/successlogin',[LoginController::class, 'successlogin'])->middleware('auth');
You can just add a new guard that will be for your accounts table and call it 'accounts' and then in your routes i.e. you can provide route grouping by guard i.e.
Route::middleware('auth:accounts')->group(function () { ...other protected routes... });
I have solved this, My way to change default auth table is correct. But I forgot to add id column there. just add this code in your New Default Auth Table Migration
$table->id();
So I have login page that the admin or users can use to login. It went well until such time we have some changes and added the admin side. I only uses 1 table for all user types and I have role_id column that defines the users role. So if the role_id is 0, I have to redirect them to the dashboard page whereas if it's a user, will redirect to user page. I have tried as what is suggested in the internet but can't make it work. Here's what I have:
class UserLoginController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest:user')->except('logout');
}
public function showLoginForm()
{
return view('auth.user-login');
}
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
// if successful, then redirect to their intended location
return redirect()->intended(route('user.dashboard'));
}
// if unsuccessful, then redirect back to the login with the form data
if (! User::where('email', $request->email)->where('password', bcrypt($request->password))->first() ) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
}
public function logout()
{
Auth::guard('user')->logout();
return redirect()->route('user.login');
}
}
config/auth
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'guest' => [
'driver' => 'session',
'provider' => 'guests',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'guests' => [
'driver' => 'eloquent',
'model' => App\Guest::class,
],
],
MODEL
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $guard = 'user';
protected $fillable = [
//fillable cols
];
//change role id data type to integer
protected $casts = [
'role_id' => 'integer',
];
}
Now, where should I insert the condition to check if it's an admin or a user?
You can try it
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (!Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
$user = Auth::guard('user')->user();
if ($user->role_id === 0) {
return redirect()->route('user.dashboard');
}
return redirect()->route('user.page');
}
Check below i have edited the method of login:
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
// Over here this condition will be true when user is successfully login
// Below is the user data i have printed in that you can check the role of user which is login.
$user = Auth::user();
print_r($user);
}
// if unsuccessful, then redirect back to the login with the form data
if (! User::where('email', $request->email)->where('password', bcrypt($request->password))->first() ) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
}
I have a Laravel(5.8) application where I have 2 roles Super Admin and Admin which are saved in two different tables admins & users. They each have their own access levels respectively. However, about 95% of the routes in the entire application are same for each of them but restricted or modified according to their access levels.
For example:
Admin can only update his own profile and has the permission to Create & View.
Super Admin can play with the list of admins and has the permission of create/update/view & delete.
Therefore I have two guards users(default) = users table and admins = admins table. But when I am adding both or the guards in a same controller it just keep redirecting and display that the page is not redirecting properly
config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'member' => [
'driver' => 'session',
'provider' => 'member',
],
...
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'member' => [
'driver' => 'eloquent',
'model' => App\Member::class,
],
],
User.php
class User extends Authenticatable
{
...
public function _login($request)
{
if(\Auth::attempt([
'email' => $request->email,
'password' => $request->password
]))
{
return [
'success' => true
];
}
else
{
return [
'success' => false
];
}
}
}
Member.php
class Member extends Authenticatable
{
...
public function _login($request)
{
if(\Auth::guard('member')->attempt([
'email' => $request->email,
'password' => $request->password
]))
{
return [
'success' => true
];
}
else
{
return [
'success' => false
];
}
}
}
HomeController.php
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
echo "<pre>";
if(\Auth::user())
{
print_r(\Auth::user());
}
else if(\Auth::guard('member')->user())
{
print_r(\Auth::guard('member')->user());
}
echo "</pre>";
}
}
If I comment the auth middleware in the __construct() then it works and displays the data of the logged in user but if keep redirecting and shows the page is not redirecting properly error.
You probably want to use $this->middleware('auth:web') or $this->middleware('auth:member') so your middleware knows which guard to use.
Anything after the : is passed to the Middleware's handle() function as arguments.
Every laravel newbie struggles with multi auth, I am no exception
I am trying to make student management system. There will two different routs for admin admin/login and for student student/login.
The student can't register itself, but he will be registered by admin.
So a student has only access to student/dashboard, registration of students will be done by the admin on admin/dashboard.
Below is the detail what I have already done:
created migration for both admin and student.
created guard for both admin and student.
modified login controller and added adminLogin and studentLogin methods.
modified RedirectIfAuthenticated middleware
Config/auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'students' => [
'driver' => 'session',
'provider' => 'students',
],
'web-admin'=>[
'driver'=>'session',
'provider'=>'admin',
],
'api' => [
'driver' => 'token',
'provider' => 'students',
'hash' => false,
],
],
'providers' => [
'students' => [
'driver' => 'eloquent',
'model' => App\Student::class,
],
'admin' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
'passwords' => [
'students' => [
'provider' => 'students',
'table' => 'password_resets',
'expire' => 60,
],
'admin' => [
'provider' => 'admin',
'table' => 'password_resets',
'expire' => 60,
],
],
LoginController.php
lass LoginController extends Controller
{
use AuthenticatesUsers;
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->middleware('guest:web-admin')->except('logout');
$this->middleware('guest:students')->except('logout');
}
public function showAdminLoginForm()
{
return view('admin.login', ['url' => 'admin']);
}
public function adminLogin(Request $request)
{
$this->validate($request, [
'admin_id' => 'required',
'password' => 'required|min:8'
]);
if (Auth::guard('admin')->attempt(['admin_id' => $request->adminid, 'password' => $request->password], $request->get('remember'))) {
return redirect()->intended('/admin/dashboard');
}
return back()->withInput($request->only('admin_id', 'remember'));
}
public function showStudentLoginForm()
{
return view('student.login', ['url' => 'student']);
}
public function studentLogin(Request $request)
{
$this->validate($request, [
'roll_no' => 'required',
'password' => 'required|min:8'
]);
if (Auth::guard('writer')->attempt(['roll_no' => $request->roll_no, 'password' => $request->password], $request->get('remember'))) {
return redirect()->intended('/student/dashboard');
}
return back()->withInput($request->only('roll_no', 'remember'));
}
}
RedirectAuthenticated.php
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
if('web_admin'==='$guard'){
return redirect('/admin/dashboard');
}
return redirect('/admin/login');
}
if (Auth::guard($guard)->check()) {
if('students'==='$guard'){
return redirect('/student/dashboard');
}
return redirect('/student/login');
}
return $next($request);
}
}
I have created two folders in the view, student and admin. They both have two files. login.blade.php and dashboard.blade.php
What laravel does it it shows login, and register under auth folder.
I want to give two routes one for /admin/login which return admin.login view.
Same for student /student/login which return student.login view.
I want to remove /register route and make the link to available on admin dashboard , there will be no admin register link.
Also restrict the user from accessing admin area.
**I don't want the whole code, just help me steps and way that I should follow or changes I have to make **
Finally I solved it. I didn't use php artisan make:auth, instead I did it from scratch. Created a fresh project, deleted User.php and the migration.
Created models Student.php and Admin.php along with migrations and controllers.
php artisan make:model Student -mc
php artisan make:model Admin -mc
After than I created guards, I deleted default guard (I don't know It was right to do so, but I felt that if there is no need of default guard and also it was using users table so I deleted).
Here is config/auth.php
'guards' => [
'student'=>[
'driver'=>'session',
'provider'=>'students'
],
'admin'=>[
'driver'=>'session',
'provider'=>'admins'
],
],
'providers' => [
'students'=>[
'driver'=>'eloquent',
'model'=>App\Student::class,
],
'admins'=>[
'driver'=>'eloquent',
'model'=>App\Admin::class,
]
So I have two guards student and admin.
Here is the admin model Admin.php
class Admin extends Authenticatable
{
use Notifiable;
protected $fillable = [
'firstname', 'lastname','admin_id', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
and model Student Student.php
class Student extends Authenticatable
{
use Notifiable;
protected $fillable = [
'firstname', 'lastname','admin_id', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
After this I modified AdminController.php
class AdminsController extends Controller
{
use AuthenticatesUsers;
protected $guard = 'admin';
public function showLogin(){
return view('admin.login');
}
public function dashboard(){
return view('admin.dashboard');
}
public function login(Request $request){
$this->validate($request,[
'admin_id' => 'required',
'password'=>'required|min:8',
]);
if(Auth::guard('admin')->attempt(['admin_id'=>$request['admin_id'], 'password'=>$request['password']])){
return redirect('admin/dashboard');
}
return redirect('/admin');
}
}
Then I created routes Web.php
Route::get('/', function () {
return view('welcome');
});
Route::get('/admin','AdminsController#showLogin');
Route::get('/student','StudentsController#showLogin');
Route::get('/admin/dashboard','AdminsController#dashboard');
Route::get('/student','StudentsController#showLogin');
Route::post('/admin/login','AdminsController#login');
Route::post('/student/login','StudentsController#login');
Now, at this time login works. I still need to do a lot. If any suggestion, I welcome that, please comment below.