I am doing two different types of auth for 'student' and 'consultant', thus two tables.
So far everything works fine. A user can choose usertype and then login, but when I'm printing {{ Auth::user()['username'] }} in the page error occurs: only 'student' name can be displayed, since I specified model and table in config/auth.php to be 'Student' and 'students'. As for consultant users, they can successfully login, but username can't be displayed.
I tried to set model and table with config during runtime but doesn't work, here's part of my AuthController:
if( $request->only('usertype')['usertype'] == 'student' ) {
Config::set('auth.model','Student');
Config::set('auth.table','students');
$userprovider = new \Illuminate\Auth\EloquentUserProvider(app('hash'), 'App\Student');
Auth::setProvider($userprovider);
$this->redirectPath = '/student/home';
}
else if( $request->only('usertype')['usertype'] == 'consultant' ) {
Config::set('auth.model','Consultant');
Config::set('auth.table','consultants');
$userprovider = new \Illuminate\Auth\EloquentUserProvider(app('hash'), 'App\Consultant');
Auth::setProvider($userprovider);
$this->redirectPath = '/consultant/home';
} $credentials = $this->getCredentials($request);
if (Auth::attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
Seems the Config::set doesn't work at all. What could be the problem?
I'm using Laravel 5.1.
Let me try answering my question, based on jedrzej's solution in the comment.
Config::set did work, but only for once and needs to be modified for every request for authentication. In this case, doing a middleware is an ideal solution - store user type in session on successful login and then in the middleware read that value from session and set config variables - laravel.com/docs/master/middleware.
Another easier solution is using some package for multi-auth. I used Sarav\Multiauth (https://packagist.org/packages/sarav/laravel-multiauth) and it works perfectly.
Related
Laravel + MongoDB
This is my Store() method in UserController:
public function store()
{
$userData = request()->get('user', []);
.
.
//Checking if credentials satisfied
.
.
try
{
$user = User::create($userData);
}
catch(BulkWriteException $ex)
{
abort(409, trans('errors.EXISTS_USERNAME'));
}
catch(Exception $e)
{
abort(409, trans('errors.EXISTS_USERNAME'));
}
return [
'status' => 'success',
'result' => $user,
];
}
Close up to the Create() method in the above Code:
public static function create($parameters)
{
return static::query()->create($parameters);
}
Close up to the Create() method in the above Code:
public function create(array $attributes = [])
{
return tap($this->newModelInstance($attributes), function ($instance) {
$instance->save();
});
}
So the problem is When I delete a User for example with username: "X" I can't make a new User with username: "X" and it gives the error u see in the exception.
The deletion method is soft-delete which means the user not completely deleted from DB it just gives the user deleted_at property so laravel will understand that act to this user like a deleted user which means when I use a query like User::where('username',"X")->get() it won't show me any result which means the data is deleted.
so here's the deal, I can't understand why it throws me exception about Existing Username while laravel can't see the user as a data.
What I want to do is fixing this issue without using force-delete and with only using soft-delete
You note that your username is a unique field.
You are using Laravel soft-deletes.
This means that Laravel keeps the record in the database, and places a non-null value inside deleted_at within your users table.
Because the data is not deleted from the database, the database cannot create a new record with the same name "X", because that record "X" already exists -- it just appears deleted to Laravel due to the soft delete.
If you want the protection of a unique user name, this is not a problem: it is working correctly by preventing you from duplicating a username against ALL users ever, even those you have had to delete. You may need to keep the user data over time (thus the soft-delete), and this would successfully prevent you from duplicating even an old 'removed' user. If you don't want this protection, remove the unique field from the username.
I can't for the life of me find info on how to do this despite my gut telling me its a basic fundamental.
I have a simple boolean that redirects users based on a table value reference_id. I want it to redirect the user after inputting a value in a column in that user's row.
Here is the code: (you can ignore the code I commeneted out. That's for a different implementation)
https://gyazo.com/9f2774cd9069b4678d67b80391f9f276
protected function redirectTo()
{
$id = Auth::id();
$rfid = DB::table('users')->where('id', $id)->value('reference_id');
//$userid = User::find($id);
if ($rfid == ''){
//$clientRole = DB::table('roles')->where('id', '2')->value('slug');
//$userid->attachRole($clientRole); // sets role based on redirect
input 'client' to database 'users' column 'temproles' //dummy code for what I want to do
view('/clientdirect');
}
else {
//$employeeRole = DB::table('roles')->where('id', '3')->value('slug');
//$userid->attachRole($employeeRole); // sets role based on redirect
input 'employee' to database 'users' column 'temproles'
view('/empdirect');
}
}
Again my apologies if this is common knowledge, I couldn't find a reference source anywhere. Either a link to where I can read about this or directions would be great!
If you want to input 'client' on a table called 'users' in a column 'temproles' you should be able to accomplish that by this:
DB::table('users')->insert(
['temprole' => 'client']
);
If you have models created you could do the following:
$user = new User
$user->temproles = 'client';
$user->save();
User.php - pretty vanilla hasMany relationship:
public function transactions()
{
return $this->hasMany('App\Transaction');
}
UserTest.php:
public function testTransactionsAttribute()
{
$user = Auth::user();
// Verify logged in user is expected user.
$this->assertTrue($user->username == 'something');
// Pay something.
$transaction = $user->payMembershipFee();
// Verify transaction is in database
$this->seeInDatabase('transactions', ['amount' => 50, 'user_id' => $user->id]);
// Verify transaction belongsTo relationship
$this->assertTrue($transaction->user->username == 'something');
// Verify user hasMany relationship - fails
$this->assertTrue($user->transactions->count() > 0, 'The user should have at least one transaction associated.');
}
Here's where it gets interesting (I did not modify the database tables - just left PHPUnit and switched to Tinker):
$ php artisan tinker
Grab user (verified is same user created from test):
$user = App\User::first()
Copy/Paste assertion:
$user->transactions->count()
=> 1
Also, when I manually go through the steps locally - it works. So, it appears Laravel 5.2 is acting as expected. However, PHPUnit is not.
I'm wondering if it's possible I'm missing something in the way Laravel 5.2 and PHPUnit work with one another?
From outside the model (in the test itself, for example):
$user = $user->fresh();
From inside the model one cannot do something like:
$this = $this->fresh();
So, inside the method that creates the Transaction for the User:
public function createTransaction()
{
$transaction = new Transaction;
...
$transaction->save();
// Refresh the relationship specifically
$this->load('transactions');
// There is also fresh([])
// which is supposed to be able to accept multiple relationships
return $transaction;
}
https://laracasts.com/discuss/channels/testing/refresh-a-model
I am trying to implement RBAC in my project by following the tutorial* on the Yii website. However I am confused when trying to implement the permissions by group.
For this example I have added a group field into the user table and have defined two groups, user (2) and admin (1).
I then created a console command which looks like this:
class RbacController extends Controller
{
public function actionInit()
{
$auth = \Yii::$app->authManager;
$rule = new \app\rbac\UserGroupRule;
$auth->add($rule);
$search = $auth->createPermission('search');
$search->description = 'Search';
$search->ruleName = $rule->name;
$auth->add($search);
$user = $auth->createRole('user');
$user->ruleName = $rule->name;
$auth->add($user);
$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
$auth->addChild($admin, $user);
}
}
And I have this file: rbac/UserGroupRule.php
class UserGroupRule extends Rule
{
public $name = 'userGroup';
public function execute($user, $item, $params)
{
// return true; // force return to true for test
if(!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->group;
if($item->name === 'search') {
return $group == 1;
}
return false;
}
}
I'm trying to test the permission with if(\Yii::$app->user->can('search')).
Firstly, I wonder why the console command is required here as I can't see where it's being used.
The $item parameter in the execute method has the value of search, but the tutorial shows that it expects this value to be role type.
Regardless of what I return in the execute method, it seems to return false.
Can anyone answer these questions?
http://www.yiiframework.com/doc-2.0/guide-security-authorization.html
I guess you have an authManager with DbManager ?
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
to init the rbac from the console just use yii rbac/init in a console (in correct project dir) then the database entries were done (before that the rbac tables should be empty)
if you haven't done yet create the tables with
yii migrate --migrationPath=#yii/rbac/migrations
$item is just the auth permission or role entry. The rule is called for every entry, if you have added a rule. In your case for permission "search" and roles "user" and "admin" the rules is executed.
your have added entries with rule checking. So if you e.g. check if the user can "search" by e.g.
if (\Yii::$app->user->can('search')) {
// can search
}
then the rule is checked or executed (which is your UserGroupRule). And in your case it would return true for admins and false for user given by the group field.
edit:
I hope you have added this to your components in your config file.
return [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
// ...
],
];
You have created 2 roles in your rbac (user/admin) and as far as i understand your are using a group column in the User table to allocate those roles to the user. And in your code you will need to have to check the permissions or roles. So from the DB the correct Entry is selected and if a Rule is attached this rule is then executed. And this checks the current user group and returns true or false. So in your case no assignments to those roles or permissions are done. It uses the Rule to return true or false depending on the user group. But here are other extensions search for yii2admin or yii2rbac, where you can also assign user to roles/permissions etc by database entries.
I would say you should get more help where you can "chat" e.g. the yii chat which is linked on the yii homepage.
I have a table in database called 'User'. All I want is to get the basic information of the user. I've tried to get data from database but the thing that keep me bugging is that I get all the data inside the table.
UserTable
|id|username|firstname|lasttname|middlename|gender|age|birthdate|address|contact_number|designation|
1 admin lee chiu kim male 47 07-22-87 cebu 0977452445 admin
2 lrose rose loo mar female 27 04-02-88 cebu 0977452445 manager
3 mgray gray men try male 37 01-22-89 cebu 0977452445 employee
UserProfile.php --> Model
<?php
class UserProfile extends Eloquent {
public $timestamps=false;
protected $table = 'users';
protected $fillable=array('firstname','lastname', 'middlename', 'gender', 'age', 'birthdate', 'address', 'contact_number', 'designation');
}
This is the model of my site.
UserProfileContoller.php --> Controller
<?php
class UserProfileController extends \BaseController {
public function index($id)
{
$userprofile = User::find($id);
return View::make('userprofile.index', array('userprofile' => $userprofile));
//return View::make('userprofile.index')->with('UserProfiles',UserProfile::get());
}
For example I am currently log in to username admin and I want to edit and view my profile. How can I get the data just for admin only. Please Help.
The situation hers is that. let say they have 3 employees. So in the table 3 username. lets assume that I'm not the admin. I will log in using lrose. and the other one log in as admin and so.on. If the three of us will go to our profiles the only thing to display there is their own profile and can edit it.
Assuming you property set-up your database why not just use the DB object?
// In the User table find the item with the username 'admin'
DB::table('User')->where('username', '=', 'admin')->get();
To get the information of some user that is logged in (given you have their username), called something like $userprofile. Then all we need to do is find by id then get the username:
// $id is the ID of the logged in user
$userprofile = User::find($id)->username; // get username of logged in user
$userprofile::find($id) will get you the information for admin only, if $id = 1.
find() only returns 1 tuple from the database.
After you call find(), you can access the data as such:
$userprofile->firstname
you mean when you pass $id to index method of User Controller all the data of other users are returned?
That's kinda weird.
$userprofile = User::find($id); change that line to $userprofile = User::find(1); and see if you can only get the data of admin.
If not, probably you are calling other method. Probably you iterate over the index method somewhere else for multiple times so that you get all the data in the database. To confirm both possibilities, just add echo 'I am in' at the entry point of your index method. If no echo message is shown, the first possibility is true. If multiple echo messages occur, the second possibility is true.
Hope this helps.
first of all, you need to use Session after login and store the id of the username in the Session.
e.g.
Step 1:
if($login) //successfull login
{
Session::put('userid', $userid);
//this id, you have to retreive it from the database after successful login
}
Step 2:
Setup the route
Route::get('profile',['uses' => 'UserProfileContoller#index']);
Step 3:
Controller
public function index()
{
if(is_null(Session::get('userid'))) return Redirect::to('login');
return View::make('userprofile.index', ['userprofile' => $this->model->index()]);
// Above code uses dependency injection to retrieve the information from db.
}
Step 4:
UserProfileModel
public function index()
{
return DB::table('user')->where('id','=', Session::get('userid'))->first();
}
p.s. i find it easier to use query builder than eloquent orm. if you want to use orm, change the code where needed.