Как контролировать доступ к маршруту с помощью Scope в Vue js и Laravel Passport? - PullRequest
0 голосов
/ 17 апреля 2020

Я создаю SPA с Vue js и Laravel, и я создал свою систему аутентификации, используя Laravel Passport. В моем приложении есть два типа пользователей: кандидаты и работодатели. Когда пользователь регистрируется, у него будет роль либо кандидата, либо работодателя, и я создал две области: кандидат и работодатель. Таким образом, пользователь с областью кандидата должен видеть только маршруты для кандидата, а пользователь с областью работодателя должен видеть только маршруты для работодателей. Имеет смысл.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь go в / api / Employer / Profile / создать в Postman, используя пользователя с областью действия кандидата, я получаю 403 Invalid scope(s) provided., что хорошо это то, что я хочу. Но когда я вхожу как этот пользователь с кандидатом в область действия и go по этому маршруту в браузере / работодателе / ​​профиле / создании, я вижу страницу.

Почему это работает в Почтальоне, но не в моем приложении?

Вот мой API. php:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::group(['prefix' => 'auth'], function() {

   Route::post('register', 'AuthController@register');
   Route::post('login', 'AuthController@login');

    Route::group(['middleware' => 'auth:api'], function () {
        Route::get('logout', 'AuthController@logout');
        Route::get('profile', 'AuthController@profile');
    });

});

Route::group(['prefix' => 'candidate'], function() {

    Route::group(['middleware' => 'auth:api'], function() {

        Route::post('profile', function() {
            return response()->json([
                'message' => 'Candidate access',
                'status_code' => 200
            ], 200);
        })->middleware('scope:candidate');

        Route::post('profile/create', function() {
            return response()->json([
                'message' => 'Candidate access',
                'status_code' => 200
            ], 200);
        })->middleware('scope:candidate');

        Route::resource('profile', 'CandidateProfileController');

    });

});

Route::group(['prefix' => 'employer'], function() {

    Route::group(['middleware' => 'auth:api'], function() {

        Route::post('profile', function() {
            return response()->json([
                'message' => 'Employer access',
                'status_code' => 200
            ], 200);
        })->middleware('scope:employer');

    });

    Route::group(['middleware' => 'auth:api'], function() {

        Route::post('profile/create', function() {
            return response()->json([
                'message' => 'Employer access',
                'status_code' => 200
            ], 200);
        })->middleware('scope:employer');

    });

});

И роутер. js:

import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home';
import Login from './views/authentication/Login';
import Register from './views/authentication/Register';
import Forms from './views/Forms';
import Dashboard from './views/Dashboard';
import Admin from './views/Admin';
import CandidateProfileIndex from './views/candidate/profile/ProfileIndex';
import CandidateProfileCreate from './views/candidate/profile/ProfileCreate';
import EmployerProfileCreate from './views/employer/profile/ProfileCreate';
import ResetPassword from './views/authentication/ResetPassword';
import * as auth from './services/auth_service.js';

Vue.use(VueRouter);

const routes = [
    {
        path: '/',
        name: 'home',
        component: Home
    },

    {
        path: '/admin',
        component: Admin,
        children: [
            {
                path: '',
                name: 'dashboard',
                component: Dashboard,
                meta: {
                    breadcrumb: 'Admin'
                },
            },

            {
                path: '/candidate/profile',
                name: 'candidate-profile-index',
                component: CandidateProfileIndex,
                meta: {
                    breadcrumb: 'My Profile'
                },
            },

            {
                path: '/candidate/profile/create',
                name: 'candidate-profile-create',
                component: CandidateProfileCreate,
                meta: {
                    breadcrumb: 'Create Profile'
                },
            },

            {
                path: '/employer/profile/create',
                name: 'employer-profile-create',
                component: EmployerProfileCreate,
                meta: {
                    breadcrumb: 'Create Profile'
                },
            },
        ],
        beforeEnter(to, from, next) {
            if (!auth.isLoggedIn()) {
                next('/login');
            } else {
                next();
            }
        }
    },

    {
        path: '/login',
        name: 'login',
        component: Login,
        beforeEnter(to, from, next) {
            if (!auth.isLoggedIn()) {
                next();
            } else {
                next('/');
            }
        }
    },

    {
        path: '/register',
        name: 'register',
        component: Register
    },

    {
        path: '/reset-password',
        name: 'resetpassword',
        component: ResetPassword
    },

    {
        path: '/forms',
        name: 'forms',
        component: Forms
    }
]

const router  = new VueRouter({
    mode: 'history',
    routes: routes,
    linkActiveClass: 'active'
});

export default router;

ОБНОВЛЕНО!

AuthServiceProvider. php:

public function boot()
    {
        $this->registerPolicies();

        Passport::tokensCan([
            'candidate' => 'view candidate routes only',
            'employer' => 'view employer routes only',
        ]);

        Passport::routes();

    }

Я добавил PassportServiceProvider в config / app. php и изменил драйвер API с токена на паспорт в config / auth. php.

'api' => [
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => false,
        ],

Вот мой системный код авторизации:

import {http, httpFile} from './http_service.js';
import jwt from 'jsonwebtoken';
import store from '../store.js';

export function register(user) {
    return http().post('/auth/register', user);
}

export function login(user) {
    return http().post('/auth/login', user)
        .then(response => {
           if (response.status === 200) {
                setToken(response.data)
           }

           return response.data;
        });
}

function setToken(user) {
    const token = jwt.sign({ user: user }, 'laravelvuespaaskjsdiowtyurweiuwuuwiueoiwuesnmbnmsdsndbs829638628');
    localStorage.setItem('laravel-vue-spa-token', token);
    store.dispatch('authenticate', user.user);
}

export function isLoggedIn() {
    const token = localStorage.getItem('laravel-vue-spa-token');
    return token != null;
}

export function logout() {
    http().get('/auth/logout');
    localStorage.removeItem('laravel-vue-spa-token');
}

export function getAccessToken() {
    const token = localStorage.getItem('laravel-vue-spa-token');
    if (!token) {
        return null;
    }

    const tokenData = jwt.decode(token);
    return tokenData.user.access_token;
}

export function getProfile() {
    return http().get('/auth/profile');
}

Чего мне не хватает?

...