How to redirect users conditionally? - php

I am on Laravel with Jetstream, I am using responses to redirect a user, once after a user registers himself. I am successfully able to redirect users whenever a user registers. Only admins can create users or invite them. So whenever I create a user from the admin panel, it redirects me to the route('frontend.dashboard') which can only be viewed by the user with a client role. So as I am logged in as an administrator, it throws me a status error 404.
How can I omit the redirection part when an administrator is registering an account. So a user is only redirected whenever he himself registers.
RegisterResponse.php
class RegisterResponse implements RegisterResponseContract
{
public function toResponse($request)
{
if(Auth::user()->hasAnyRoles(['Administrator', 'Employee'])) {
return redirect()->route('backend.dashboard');
}
return redirect()->route('frontend.dashboard');
}

You can use middleware to restrict user to redirect different routes.
Otherwise you can create two tables named "permissions" and "features" in your database.
Table columns should be like this:
- Table(Permissions):
Schema::create('permissions', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('user_id');
$table->unsignedInteger('feature_id');
$table->timestamps();
});
- Table(Features):
Schema::create('features', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Now make a helper function like this which will check if the particular user has access to redirect to the particular route.
**
Helper function:
**
function has_permission($feature_name)
{
$user = Auth::user();
if($user->role->name == 'admin' ){
$status = True;
}else{
$feature = Feature::where('name', $feature_name)->first();
$status = Permission::where([['user_id', $user->id],['feature_id', $feature->id]])->exists();
}
return $status;
}
So, now you can add condition in your Controllers every functions which redirect to a page like this:
if (!has_permission('shipments')) {
$notification=array(
'message' => 'Sorry ! You do not have permission',
'alert-type' => 'warning'
);
Thank you.Happy coding

Related

Larevel - Save last user request timestamp

I want to save the datetime of last interaction of a user with the application inside the user table.
I'm using Laravel 8.
I added a column in users table (last_interaction):
Schema::create('users', function(Blueprint $table)
{
$table->engine = 'InnoDB';
$table->integer('id', true);
$table->string('firstname');
$table->string('lastname');
$table->string('username', 192);
$table->string('email', 192);
$table->string('password');
$table->string('avatar')->nullable();
$table->string('phone', 192);
$table->integer('role_id');
$table->boolean('statut')->default(1);
$table->datetime('last_interaction'); //The column where to save the datetime of last interaction
$table->timestamps(6);
$table->softDeletes();
});
Is it possible to update the users table with each request done! or should i do it on login only (for Optimisations) ?
You can make new middleware with this command php artisan make:middleware LastInteraction
App\Http\Middleware\LastInteraction.php:
public function handle(Request $request, Closure $next)
{
if (Auth::check()) {
$user = Auth::user();
$user->last_interacted = Carbon::now();
$user->save();
}
return $next($request);
}
This will set a field of last_interacted to the current time given this field exists in your migration. If it doesn't exist create one.
App\Http\Kernel.php
protected $middleware = [
(...)
\App\Http\Middleware\LastInteraction::class,
];
This will register the middleware to be applied globally to each route.

Laravel 5.1 login with mfa token

I'm trying to get the a login with mfa to work. I'm using the https://github.com/antonioribeiro/google2fa package.
Basically the user-migration looks like this
class CreateUsersTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up() {
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->string('google2fa_secret');
$table->boolean('useMfa')->default(false);;
$table->timestamps();
});
}
...
If the user has not yet activated mfa I create a new secret every time the user opens the profile page.
if(!$user->useMfaToken()){
$google2fa = new Google2FA();
$user->google2fa_secret = $google2fa->generateSecretKey();
$user->save();
$google2fa_url = $google2fa->getQRCodeGoogleUrl(
'DatenPro.de',
$user->email,
$user->google2fa_secret
);
}
If the user enters the secret for finalizing the activation of mfa this will be executed:
public function saveMfa(){
$user = \Auth::user();
$secret = \Input::get('secret');
$google2fa = new Google2FA();
$valid = $google2fa->verifyKey($user->google2fa_secret, $secret);
if($valid){
$user->useMfa = true;
$user->save();
return redirect()->back()->withMessage('mfa sucessfully activated');
}
...
Now I'm working on the login with a mfa-token. I want that the user has the option to enter the token at the login page, if he has already activated it, otherwise if the mfa-Checkbox is deselected the "secret" text-input is hidden.
Email: __________
Password: __________
Use Mfa: [x]
Secret: __________
Where do I have to put the checks of the mfa token? I have read about it to check it through a middleware and a session-variable, but this seems kind of wrong.
Just figured it out before posting.
You can implement a "authenticated"-method in the AuthController.
This could look like this:
public function authenticated($request, $user){
if($user->useMfaToken()){
$secret = \Input::get('secret');
$google2fa = new Google2FA();
$validMfaToken = $google2fa->verifyKey($user->google2fa_secret, $secret);
}else{
$validMfaToken = true;
}
if($validMfaToken){
return redirect()->intended('dashboard');
}
Auth::logout();
return redirect($this->loginPath)
->withInput($request->only('email', 'remember'))
->withErrors([
'secret' => 'mfa token was not corret',
]);
}

Laravel 5 SQLSTATE[23000] users_email_unique

I am implementing a social authentication on my website with laravel 5.
I successfully logged in a couple of users but now for some very strange reasons it doesn't work anymore..
When I try to log in a new user I have this error coming up:
QueryException in Connection.php line 624:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'users_email_unique' (SQL: insert into `users` (`name`, `profile_picture`, `facebook_id`) values (Hwan, https://graph.facebook.com/v2.4/1701160536770162/picture1701160536770162type=normal, ?))
But this user has never been registered in the DB before !!
I tried with other users, all the same...
But if I remove an existing FB user from the DB and try again, it works !!
Here is my controller:
class AccountController extends Controller {
/**
* Redirect the app to the social provider
*
* #return SNS token and user data
*/
public function redirectToProvider($provider) {
return Socialize::with($provider)->redirect();
}
/**
* Callback handler
*
* #return redirect to index
*/
public function handleProviderCallback($provider) {
$user = Socialize::with($provider)->user();
// get the sns user data
$id = $user->getId();
$name = $user->getName();
$avatar = $user->getAvatar();
// get the user provider id form the DB
$users = DB::table('users')->where($provider.'_id', $id)->get();
// check if the record exists
if(empty($users)){
DB::table('users')->insert(
['name' => $name,'profile_picture' => $avatar,$provider.'_id' => $id]
);
$users = DB::table('users')->where($provider.'_id', $id)->get();
}
foreach ($users as $user)
{
$userID = $user->id;
}
Auth::loginUsingId($userID);
{
return redirect()->to('home');
}
}
}
And my routes:
Route::get('connect/{provider}', 'AccountController#redirectToProvider');
Route::get('account/{provider}', 'AccountController#handleProviderCallback');
And my user schema:
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->string('profile_picture');
$table->text('facebook_id');
$table->rememberToken();
$table->timestamps();
});
Any help is greatly appreciated
Thank you
You have a unique constraint on your email field but you do not appear to be inserting an email address. After one user is inserted without an email address, no other users can be signed up without an email address.
You will not be able to have two empty strings in the email column of your database.

Guest Student and Admin authentication

I am trying to manage user roles with Laravel 4, but I can't clearly understand how it works, so I am gonna need some explanations.
This is what I want to do:
If user is guest (not logged in), redirect to route /
If logged user role is equal to student, redirect to student/books
If logged user role is equal to admin, relocate to admin/index
What I want is to filter with slug and user role. The user table has the following columns:
first_name | email | password |role
How can I get to this, btw. I'm a newbee in Laravel so I will need a better explanation.
I assume the steps that I need are:
To create a filter in filters.php
To create route groups in routes.php
I assume that you have store user roles inside session Auth::user()->role
filters.php
Route::filter('isAdmin', function()
{
if (Auth::guest() || Auth::user()->role !== "admin")
{
return Redirect::to('/');
}
elseif(Auth::user()->role == "admin"){
}
});
Route::filter('isStudent', function()
{
if (Auth::guest() || Auth::user()->role !== "student")
{
return Redirect::route('adm_index');
} }
elseif(Auth::user()->role == "student"){
return Redirect::route('std_books');
}
});
routes.php
Route::group(array('before' => 'isStudent'), function()
{
Route::get('student/books',array('as'=>'std_books','uses'=>'BookController#method_name'));
});
Route::group(array('before' => 'isAdmin'), function()
{
Route::get('admin/index',array('as'=>'adm_index','uses'=>'AdminController#method_name'));
});

Laravel Auth::attempt() Fails after password change

My Laravel authentication works perfectly. I included password change feature. After changing the password,the login works fine for all users except the first user(uid="1"). Only the default password hash works well for this user. For other password hashes the login attempt fails. My codes are given below:
User Controller Signin
public function postSignin() {
if (Auth::attempt(array('email'=>Input::get('email'), 'password'=>Input::get('password')))) {
return Redirect::to('users/dashboard')->with(array('message' => 'You are now logged in!', 'email' => Input::get('email')));
} else {
return Redirect::to('users/login')
->with('message', 'Your username/password combination was incorrect')
->withInput();
}
}
Table Schema
Schema::create('users', function($table)
{
$table->increments('id');
$table->string('firstname', 20);
$table->string('lastname', 20);
$table->string('email', 100)->unique();
$table->string('password', 255);
$table->string('remember_token', 255);
$table->timestamps();
});
Password Change Controller function
public function postUpass() {
$user = User::find(Input::get('uid'));
if((Input::get('password'))==(Input::get('passconf'))){
$user->password = Hash::make(trim(Input::get('password')));
$user->save();
echo "Done";
//echo Hash::make(trim(Input::get('password')));
}
else {
echo "Check Passwords Again";
}
Someone please help me with this.
I can't comment yet, so I have to ask for your view by posting an answer. Though I would like to also suggest changing the way you are accessing the user in the postUpass function as that could easily be changed by the end user to update another user's password.
//change this
$user = User::find(Input::get('uid'));
//to this
$user = Auth::user();
//since the user needs to be logged in
//to change their password anyway
Also, are you saying that once you post to the postUpass function you are always being returned the 'Check passwords again' notice?

Categories