0

I'm building a SPA with Laravel in backend and VueJS2 as frontend provider. The application will handle users with 3 kind of roles: UserRole1, UserRole2 and Admin. When a user signup to the application, he select if he wants to be a user with Role1 or a user with Role2 (admin-user is set by me directly in the mysql database). So in the database there is a table "users" with a field called "role":

  • UserRole1 => "role"=1;
  • UserRole2 => "role"=2;
  • Admin => "role"=7.

When an user login, I want to redirect him to his role-based dashboard, so I have 3 different Vue components and 3 routes, and I want to prevent an user with Role1 (or Role2) from access to Role2 or Admin dashboard. Obviously, if a guest try to access to the dashboard, it will be redirected to the login page, and if an authenticated user try to access guest pages (like the Register page), it will be redirected to the dashboard page.

I would like to set a "userRole" parameter for each route, as below:

    {
        path: '/app/userRole1/Dashboard',
        component: DashboardUserRole1,
        name: 'dashboardRole1',
        meta: {
            title: 'Dashboard Role1',
            userRole: 1
        },
    },
    {
        path: '/app/userRole2/Dashboard',
        component: DashboardUserRole2,
        name: 'dashboardRole2',
        meta: {
            title: 'Dashboard Role2',
            userRole: 2
        },
    },
    {
        path: '/app/Admin/Dashboard',
        component: DashboardAdmin,
        name: 'dashboardAdmin',
        meta: {
            title: 'Dashboard Admin',
            userRole: 7
        },
    },

I've tried with Laravel Passport API and now I'm trying with JWT and websanova/vue-auth, so in the "Login" component there is a post request to the "api/auth/loign" route, that pass the data to the AuthController@authenticate method, that return a json response. But the vue-auth package is not so suitable for my needs, so I think that there could be a more efficient solution but actually I can't figure out how to write an appropriate code. I would like to know if you have some ideas.

1 Answer 1

1

A simple solution is to define an api route for retrieving information about the authenticated user. Laravel's default api.php routes file contains this route:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

You could modify it to include whatever information that your application needs to know about a user in order to handle routing logic:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user()->load('roles');
});

Then your flow looks like this:

  1. Log in normally.
  2. Immediately call /api/user, and store the response.
  3. Use the stored roles to route to the correct view in your SPA.

If the confusion is around Step 3, then this stackoverflow question might help.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi Travis, thank you for your answer. I have doubts about storing user data in localstorage. In the store.js the are "getToken" and "getUserRole" actions, that are called by the "login" method in Login component so the oauth token and the userRole value are stored in localStorage and set in Vuex store. In the app.js file there is a "router.beforeEach" guard that check if a token is set (user authenticated) and if an userRole is set, so it redirect the user to the correct route path. But both access_token and userRole in localstorage are manipulable by the user. Are there ways to prevent this?
If by "manipulated by the user" you mean a user can open dev tools and change them, that shouldn't be a problem as long as the api has proper authorization checks before returning data. If you're expecting views stored on the client side to be secured from manipulation in any way, that simply is not possible.
Yes, I meant the change of the data stored in localStorage through devtools. So, as I understand it, I can prevent the "manipulation" of the access_token value using the "auth:api" middleware (that check if the token is the same stored in the database), and I can prevent the manipulation of the userRole value using another middleware coded by me ("userRole:api"), that check if the userRole stored in localStorage is the same value stored in the "role" field of the "users" table in the database.
You're correct that the token sent by Passport (or your JWT implementation) can't be manipulated by the user because it's signed and verified by your secret key on the backend. To clarify, the point I was trying to make is that if you have authorization logic on the frontend (like only show the admin view to an admin) then there is nothing you can do to prevent someone from manipulating your frontend code to show those views. However, this is not a problem so long as the sensitive data which is displayed in those views comes from an api endpoint that does verify roles of the user.
Now it's all clear. Thank you so much for your explanations. I'll try to implement this authentication logic in my project as soon as possibile, then I'll update my question with the code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.