Simulating Role Switching Without Losing Admin Privileges in Laravel & Vue
Simulating Role Switching Without Losing Admin Privileges in Laravel & Vue In many applications, you might need to let administrators “switch” into another role—say, to preview the system as an employee—without permanently losing their admin privileges. In this post, we'll explore a session-based approach that lets an admin act as an employee (or vice versa) without actually removing or altering roles in the database. This ensures that when the switch is undone, the admin’s full permissions remain intact. Why Not Remove Roles? By default, role-based permission systems like Spatie's Laravel Permission assign a set of permissions to a user based on their roles. If you physically remove the admin role and assign the employee role, you lose the permissions associated with the admin role. This is usually undesirable since admins need their full set of privileges available whenever required. Instead, you can simulate role switching by storing an "active role" flag in the session. This way, the user’s assigned roles in the database remain unchanged, but your application can use the session flag to decide which UI elements or permissions to apply in a given context. The Session-Based Approach How It Works Storing the Active Role: When an admin chooses to "switch" roles, your backend updates a session variable (e.g., active_role) to the selected role. Using the Active Role in Your App: Backend: When returning data for a view, attach the active_role (either from the session or a default value) to the user data. Frontend: In your Vue component, check the passed active_role and adjust which actions or components are rendered. For example, if the active role is 'admin', you can bypass certain permission checks. Reverting the Switch: Since the admin role is still assigned in the database, you can easily allow the user to revert back by updating the session flag. Implementation Details Below, we break down the implementation into three parts: updating the Laravel controller, (optionally) enhancing the User model, and updating the Vue component. Laravel Controller Updates a. Returning the Active Role In your controller's index method, check if there's an active role in the session. If not, default to the user's primary role: php Copy Edit public function index() { $user = User::with([ 'unit', 'department', 'designation', 'office', 'permissions', 'roles' ])->find(auth()->id()); // Determine the default active role from the user's assigned roles. $defaultActiveRole = $user->getRoleNames()->first(); // Use session('active_role') if available, otherwise the default role. $activeRole = session('active_role', $defaultActiveRole); $user->active_role = $activeRole; $roles = $user->getRoleNames(); $permissions = $user->getAllPermissions()->pluck('name'); return view('account.index', [ 'user' => $user, 'roles' => $roles, 'permissions' => $permissions, ]); } b. Creating a Switch Role Endpoint This method updates the session when a user switches roles: php Copy Edit use Illuminate\Http\Request; public function switchRole(Request $request, $role) { // Define allowed roles for switching (adjust as needed) $allowedRoles = ['admin', 'employee']; if (in_array($role, $allowedRoles)) { session(['active_role' => $role]); return response()->json(['role' => $role]); } return response()->json(['error' => 'Invalid role'], 422); } Add a route for this endpoint in your routes/web.php: php Copy Edit Route::post('/switch-role/{role}', [UserAccountController::class, 'switchRole']); (Optional) Enhance the User Model To simplify retrieving the active role, you can add an accessor to your User model: php Copy Edit public function getActiveRoleAttribute() { // Return the session's active role, or default to the first assigned role. return session('active_role', $this->getRoleNames()->first()); } Now, you can simply use $user->active_role anywhere in your application. Vue Component Updates In your Vue component, use the active role to determine which actions are available. For instance, bypass permission checks for admins by using user.active_role: vue Copy Edit {{ user.firstname }} {{ user.lastname }} mdi-email {{ user.email }} mdi-phone {{ user.phone }} mdi-domain {{ user.unit.name }} mdi-briefcase {{ user.designation.name }} {{ action.

Simulating Role Switching Without Losing Admin Privileges in Laravel & Vue
In many applications, you might need to let administrators “switch” into another role—say, to preview the system as an employee—without permanently losing their admin privileges. In this post, we'll explore a session-based approach that lets an admin act as an employee (or vice versa) without actually removing or altering roles in the database. This ensures that when the switch is undone, the admin’s full permissions remain intact.
Why Not Remove Roles?
By default, role-based permission systems like Spatie's Laravel Permission assign a set of permissions to a user based on their roles. If you physically remove the admin role and assign the employee role, you lose the permissions associated with the admin role. This is usually undesirable since admins need their full set of privileges available whenever required.
Instead, you can simulate role switching by storing an "active role" flag in the session. This way, the user’s assigned roles in the database remain unchanged, but your application can use the session flag to decide which UI elements or permissions to apply in a given context.
The Session-Based Approach
How It Works
Storing the Active Role:
When an admin chooses to "switch" roles, your backend updates a session variable (e.g., active_role) to the selected role.
Using the Active Role in Your App:
Backend:
When returning data for a view, attach the active_role (either from the session or a default value) to the user data.
Frontend:
In your Vue component, check the passed active_role and adjust which actions or components are rendered. For example, if the active role is 'admin', you can bypass certain permission checks.
Reverting the Switch:
Since the admin role is still assigned in the database, you can easily allow the user to revert back by updating the session flag.
Implementation Details
Below, we break down the implementation into three parts: updating the Laravel controller, (optionally) enhancing the User model, and updating the Vue component.
- Laravel Controller Updates a. Returning the Active Role In your controller's index method, check if there's an active role in the session. If not, default to the user's primary role:
php
Copy
Edit
public function index()
{
$user = User::with([
'unit',
'department',
'designation',
'office',
'permissions',
'roles'
])->find(auth()->id());
// Determine the default active role from the user's assigned roles.
$defaultActiveRole = $user->getRoleNames()->first();
// Use session('active_role') if available, otherwise the default role.
$activeRole = session('active_role', $defaultActiveRole);
$user->active_role = $activeRole;
$roles = $user->getRoleNames();
$permissions = $user->getAllPermissions()->pluck('name');
return view('account.index', [
'user' => $user,
'roles' => $roles,
'permissions' => $permissions,
]);
}
b. Creating a Switch Role Endpoint
This method updates the session when a user switches roles:
php
Copy
Edit
use Illuminate\Http\Request;
public function switchRole(Request $request, $role)
{
// Define allowed roles for switching (adjust as needed)
$allowedRoles = ['admin', 'employee'];
if (in_array($role, $allowedRoles)) {
session(['active_role' => $role]);
return response()->json(['role' => $role]);
}
return response()->json(['error' => 'Invalid role'], 422);
}
Add a route for this endpoint in your routes/web.php:
php
Copy
Edit
Route::post('/switch-role/{role}', [UserAccountController::class, 'switchRole']);
- (Optional) Enhance the User Model To simplify retrieving the active role, you can add an accessor to your User model:
php
Copy
Edit
public function getActiveRoleAttribute()
{
// Return the session's active role, or default to the first assigned role.
return session('active_role', $this->getRoleNames()->first());
}
Now, you can simply use $user->active_role anywhere in your application.
- Vue Component Updates In your Vue component, use the active role to determine which actions are available. For instance, bypass permission checks for admins by using user.active_role:
{{ user.firstname }} {{ user.lastname }}
mdi-email
{{ user.email }}
mdi-phone
{{ user.phone }}
mdi-domain
{{ user.unit.name }}
mdi-briefcase
{{ user.designation.name }}
{{ action.icon }}
{{ currentAction.title }}
Current Role: {{ user.active_role }}
Save
Cancel
Debug Info
{{ JSON.stringify(user, null, 2) }}
{{ JSON.stringify(roles, null, 2) }}
{{ JSON.stringify(permissions, null, 2) }}
export default {
props: {
user: Object,
roles: Array,
permissions: Array
},
data() {
return {
// Define actions with their permission requirements.
actions: [
{
title: 'Switch Role',
icon: 'mdi-account-switch',
type: 'switch',
field: 'role',
permissionRequired: 'switchrole'
},
{
title: 'Edit Profile',
icon: 'mdi-pencil',
type: 'edit',
field: 'fullname',
label: 'Full Name',
rules: [(v) => !!v || 'Full name is required'],
permissionRequired: 'edit_user'
},
// Other actions...
],
// Available roles for switching.
availableRoles: ['admin', 'employee'],
dialog: false,
currentAction: null,
formData: {
fullname: '',
password: '',
email: '',
phone: '',
role: ''
}
};
},
computed: {
filteredActions() {
// Bypass permission checks if the active role is 'admin'
if (this.user.active_role === 'admin') {
return this.actions;
}
// Otherwise, filter actions based on the required permission.
return this.actions.filter((action) => {
if (action.permissionRequired) {
return this.permissions.includes(action.permissionRequired);
}
return true;
});
}
},
mounted() {
console.log('User:', this.user);
console.log('Roles:', this.roles);
console.log('Permissions:', this.permissions);
},
methods: {
openModal(action) {
this.currentAction = action;
// For switch role, pre-populate the field with the active role.
if (action.type === 'switch') {
this.formData.role = this.user.active_role;
}
this.dialog = true;
},
async executeAction() {
// Validate edit actions, if necessary.
if (this.currentAction.type === 'edit' && this.$refs.editForm && !this.$refs.editForm.validate()) {
return;
}
switch (this.currentAction.type) {
case 'edit':
this.user[this.currentAction.field] = this.formData[this.currentAction.field];
break;
case 'switch':
try {
const response = await axios.post(`/switch-role/${this.formData.role}`);
this.user.active_role = response.data.role;
console.log(`Switched active role to ${this.user.active_role}`);
} catch (error) {
console.error('Failed to switch role:', error);
}
break;
default:
break;
}
this.dialog = false;
}
}
};
Conclusion
This session-based role switching approach ensures that:
Administrators can temporarily switch their operational context (to view or test employee functionality) without losing their original admin privileges.
Backend data remains intact, as no roles are removed or reassigned in the database.
Frontend logic adapts based on the active role, giving you full control over which UI elements and permissions are in effect