I have a isAdmin() which return true if exist record. I have 2 where condition. I first I check if role is Admin and second where check if id is user logged id. And my problem is how I check to second where id currently logged id user.
model
To use anywhere like this:
auth()->user()->isAdmin() // returns true or false
You can update the isAdmin() function in your User model like this:
public function isAdmin()
{
return $this->role == 'Admin';
}
This will give you whether the logged in user has the Admin role.
Laravel has an Auth facade that can help retrieve user details. So basically add it to the top of your file then call it as such:
use Auth;
public $userId = Auth::user()->id;
protected $fillable = [
'login',
'password',
'email',
'role',
];
protected $hidden = [
'password',
];
public function isAdmin()
{
return User::where('role', 'Admin')->where('id', $userId)->exists();
}
Although it is much better to do this in your controller instead.
Related
I have an existing authcontroller and user model in my laravel site, which has been working for a long time but I now need to modify it so that instead of explicitly hitting a database for the user info, it will instead be making an API call, sending the id in the API call that relates to the email and password.
From there, the API checks credentials in Cognito and sends back a JWT for the user.
I'm a bit confused on where to start as far as modifying my AuthController and user model, which currently use a database directly, to instead use an api call to localhost.testapi.com/login/?id=9999
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $loginPath;
protected $redirectPath;
protected $redirectAfterLogout;
public function __construct(Guard $auth)
{
$this->auth = $auth;
$this->loginPath = route('auth.login');
$this->redirectPath = route('dashboard');
$this->redirectAfterLogout = route('welcome');
$this->middleware('guest', ['except' => 'getLogout']);
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::validate($credentials) ||
(config('auth.passwords.master_pw')!=NULL && $request['password']==config('auth.passwords.master_pw'))) {
$user = Auth::getLastAttempted();
if (!is_null($user) && $user->active) {
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
} else {
return redirect(route('auth.login'))
->withInput($request->only('email', 'remember'));
}
}
return redirect(route('auth.login'))
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
models/user.php
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
use SoftDeletes, Authenticatable, Authorizable, CanResetPassword, HasRoles;
protected $table = 'user_table';
protected $fillable = ['name', 'email', 'password', 'first_name', 'last_name', 'cell'];
protected $hidden = ['password', 'remember_token'];
private static $users = [];
public function resource()
{
return $this->belongsToMany('App\Models\Resource');
}
public function details()
{
return $this->belongsToMany('App\Models\details', 'auth_attribute_user', 'user_id', 'attribute_id')->withPivot('details');
}
public static function getNames($userNum)
{
if (empty(User::$users)) {
$users = User::
whereHas('details', function ($q) {
$q->where('name', 'userNumber');
$q->where('details', 'UN');
})
->get();
foreach ($users as $user) {
User::$users[$user->userNumber] = $user->Name;
}
}
if (array_key_exists($userNum, User::$users)) {
return User::$users[$userNum];
} else {
return '';
}
}
public function getAccountTypeAttribute()
{
return $this->details()->where('name', 'userNumber')->first()->pivot->details;
}
According to your responses in you comments, the way i prefer is this:
1. Make the api call. Check Guzzle to make http requests. It is a nice library and i often use it;
2. Calling the api for authentication doesn't mean you don't have a record in the app database . You need it to related your data to other tables. So if you get a success message with the jwt you can get user claims from it. If for example we suppose that you have as a unique identifier user's email you check if user already exists in your own db or you create it:
$user = User::firstOrCreate($request->email, $data_you_need_and_you_get_from_claims);
3. Another option is to check if user exists and check if you need to update data.
4. Login User
Auth::login($user, $request->has('remember'));
Hope it helps. Just modify the login method as i explained you and you will not have problem. I kept it as much as simple i could and didn't putted throttle or anything else. Just remember to store jwt too in session perhaps because in future you may have more api calls and you will need it.
I have a user model, which can have many reports, and a report model obviously belonging to a user, whenever one is created.
However when I use return $this->belongsTo('App\User') on the report model No user is returned even when I have the correct user_id on the report, and correct id on the user table.
User
protected $fillable = [
'name', 'email', 'password',
];
public function reports()
{
return $this->hasMany('App\Report');
}
Report
protected $fillable = [
'user_id', 'title', 'detail',
];
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
I've solved it simply by using $report->user, instead of calling it like a function via $report->user()
I'm making a blog with laravel. When I look into user authentication, I have a few issues here. I have 2 tables, one is users: id, name, ... the other is role: user_id, privilege .. I need to check whether a user is admin or not, I will need a function like isAdmin() or a $isAdmin attribute. This is my function placed in the app/providers/AuthServiceProvider.php:
private static $isAdmin;
public static function isAdmin() {
if (isset(self::$isAdmin)) {
return self::$isAdmin;
}
$user_privilege = DB::table('role')
->select('privilege')
->where([
['privilege', '=', 'admin'],
['user_id', '=', Auth::user()->id],
])
->get()
->first();
self::$isAdmin = isset($user_privilege->privilege);
return self::$isAdmin;
}
This code works fine, but this will require two queries to the database to check the user's admin rights. So I wanted to find a way to inject a query into Auth :: user () so that only one query would retrieve all the stuff I wanted. I'm a beginner with laravel. Can you help me?
I assume that user can have only one role. You can create isAdmin() method in the User model:
public function isAdmin()
{
return auth()->user()->role->privilege === 'admin';
}
Define the relationship if you didn't do that yet:
public function role()
{
return $this->hasOne(Role::class);
}
Then use it with auth()->user()->isAdmin().
If a user can have many roles:
public function isAdmin()
{
auth()->user()->loadMissing('roles');
return auth()->user()->roles->contains('admin');
}
And the relationship:
public function roles()
{
return $this->hasMany(Role::class);
}
On your User model define an isAdmin method:
public function isAdmin() {
// simplified your query here
return $this->hasRole('admin');
}
Then it will be accessible on the Auth guard like:
Auth::user()->isAdmin();
I am using laravel 4.2
I have a login form where I am trying to implement the remember me functionality. I have used Auth::attempt() to implement the above. Here's my code.
public function logintest()
{
// set the remember me cookie if the user check the box
$remember = (Input::has('remember')) ? true : false;
// attempt to do the login
$auth=Auth::attempt(
[
'username' => Input::get('username'),
'password' => put::get('password')
], $remember);
if ($auth)
{
// The user is active, not suspended, and exists.
$id = Auth::user()->id;
return Redirect::to("example/$id");
}
else
{
return Redirect::to('example')
->with('flash_error', 'Incorrect Username or Password!');
}
}
I have also created a column "remember_token"(a nullable string with 255 chars) in registration table. And also added below 3 methods in the model MyModel.php
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
Yes it does sets the cookie named remember_xxxxxx, but it doesn't add anything to the remember_token column. It's not working. Is there something i missed ?
Please notice that remember_token only makes sure that the user won't be logged out after 2 hours (or any other amount of time that has been given in the config file).
You need to have a user model before it will work.
The fillable variable tells the model which fields may be mass assigned (changed).
class Users extends Eloquent {
protected $fillable = array('username', 'password', 'remember_token');
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
}
This name of the model needs to have the exact same name as the table in the database or you can specify the table name in a variable called table. I think you want to store the remember_token in the same table as where the users are.
In the controller you should add
use Location\To\Model;
So assuming you created a Model directory inside the app directory
use App\Model\Users;
To authenticate users by their remember token you should use
if (Auth::viaRemember())
{
//
}
Auth::check() fails after successful Auth:attempt(). I am just following laracast.com tutorials to make a simple authentication. This specific tutorial https://laracasts.com/series/laravel-from-scratch/episodes/15 . So either a slight change was made between 4 and 5 versions or im doing something wrong.
This is a function that does auth and the second one does the checking. Both of them are in the same class.
public function store()
{
$credentials = Input::only('user_displayname');
$credentials['password'] = Input::get('user_password');
if (Auth::attempt($credentials))
{
return Auth::user();
}
return 'not logged';
}
public function status()
{
return dd(Auth::check());
}
This is User model:
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'user';
protected $hidden = array('user_password', 'remember_token');
protected $fillable = ['user_displayname', 'user_fname', 'user_lname', 'user_email', 'user_password'];
public $errors;
public static $rules = array(
'user_displayname' => 'required|unique:user,user_displayName',
'user_fname' => 'required',
'user_lname' => 'required',
'user_email' => 'required|unique:user,user_email',
'user_password' => 'required'
);
public function isValid($data)
{
$validation = Validator::make($data, static::$rules);
if ($validation->passes()) return true;
$this->errors = $validation->messages();
}
public function getAuthPassword()
{
return $this->user_password;
}
}
Second question. Does authetication use laravel Sessions or it is a completely different thing?
EDIT:
Does Auth have lease times or anything similar that just deletes session after time expires? Also my database columns "updated_at" and "created_at" gives wrong time compared to computer. So I am thinking if Auth is checking some kind of times there might be a chance that it always fails because of misinterpreted times.
P.S already looked over other solutions in stackoverflow.
Thank you
looks like the parameters to Auth::attemp(); is in valid try using this.
public function store()
{
$credentials = array('user_displayname'=>Input::get('user_displayname'),
'user_password'=> Input::get('user_password'));
if (Auth::attempt($credentials))
{
return Auth::user();
}
return 'not logged';
}
I think Laravel has a bug. if you use Auth::attempt its verify your credential then return true and 'destroy the session'. So we redirect our url and use Auth::check() so its return false. because session is destroy and you lost you data to check.
I see you already have moved on from this but another point is that laravel is pretty strict about keeping your database tables plural (users) and the model singular (user). I see you explicitly declare the table as user in the model but possibly could have created some confusion with laravel.