Введение. Laravel - это самая быстрорастущая среда PHP, которую используют тысячи разработчиков по всему миру для быстрого создания надежных веб-приложений. Vue, с другой стороны, представляет собой легкую интерфейсную структуру, которую можно использовать для создания сложных одностраничных приложений.
Объединив возможности этих великолепных фреймворков, разработчики могут с легкостью создавать очень мощные приложения. Хорошей новостью является то, что интегрировать vue в laravel легко, поскольку laravel имеет встроенную поддержку vue.
Это руководство проведет вас через процесс предоставления аутентификации для вашего одностраничного приложения vue (SPA), чтобы иметь возможность доступа к конечным точкам API в laravel, требующем аутентификации.
Ресурсы: В этом руководстве были использованы следующие ресурсы.
- NodeJS 8.9.1
- Laravel 5.5
- jwt-auth 0.5.12
- NPM 5.6.0
- VueJS 2.5.7
- Vue-роутер
- Vue-axios
- @ websanova / vue-auth
Настройка
- Создайте проект laravel, выполнив следующую команду на своем терминале.
composer create-project laravel/laravel lara-vue-auth –prefer-dist
- Перейдите в каталог проекта, выполнив следующую команду на своем терминале.
cd lara-vue-auth
- Затем вам нужно будет установить зависимости javascript, выполнив следующую команду на своем терминале.
npm install
- Затем укажите учетные данные своей базы данных в файле .env и создайте базу данных для использования с вашим приложением (если она еще не существует).
- Затем запустите миграцию базы данных, чтобы создать таблицу users и таблицу password_resets, выполнив следующую команду на своем терминале.
php artisan migrate
- Установите некоторые библиотеки vue, которые нам понадобятся. Выполните следующую команду на своем терминале.
npm install --save-dev vue-axios vue-router vue-loader vue-template-compiler
- Создайте файл с именем App.vue в resources / assets / js и поместите в него следующее содержимое.
<template>
<div class="panel panel-default">
<div class="panel-heading">
<nav>
<ul class="list-inline">
<li>
<router-link :to="{ name: 'home' }">Home</router-link>
</li>
<li class="pull-right">
<router-link :to="{ name: 'login' }">Login</router-link>
</li> <li class="pull-right">
<router-link :to="{ name: 'register' }">Register</router-link>
</li>
</ul>
</nav>
</div>
<div class="panel-body">
<router-view></router-view>
</div>
</div>
</template>
- Создайте еще один файл с именем Home.vue, но теперь в resources / assets / js / components и поместите в него следующий код.
<template>
<h1>Laravel 5 Vue SPA Authentication</h1>
</template>
- Затем замените содержимое файла resouces / assets / js / app.js приведенным ниже кодом.
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import Home from './components/Home.vue';
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{
path: '/',
name: 'home',
component: Home
},
]
});
new Vue({
el: '#app',
router: router,
render: app => app(App)
});
- Затем замените содержимое файла шаблона resources / views / welcome.blade.php приведенным ниже кодом.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div id="app"></div>
</div>
<script src="/js/app.js"></script>
</body>
</html>
Теперь запустите следующую команду на своем терминале.
npm run watch
потом
php artisan serve
Зайдите в свой браузер и посетите http: // localhost: 8000. Если у вас все прошло хорошо, вы сможете увидеть свою домашнюю страницу.
Создание компонентов Vue
Давайте создадим необходимые нам компоненты vue.
Создайте файл с именем Register.vue в каталоге resources / assets / js / components и поместите в него следующий код.
<template> <div> <div class="alert alert-danger" v-if="error && !success"> <p>There was an error, unable to complete registration.</p> </div> <div class="alert alert-success" v-if="success"> <p>Registration completed. You can now <router-link :to="{name:'login'}">sign in.</router-link></p> </div> <form autocomplete="off" @submit.prevent="register" v-if="!success" method="post"> <div class="form-group" v-bind:class="{ 'has-error': error && errors.name }"> <label for="name">Name</label> <input type="text" id="name" class="form-control" v-model="name" required> <span class="help-block" v-if="error && errors.name">{{ errors.name }}</span> </div> <div class="form-group" v-bind:class="{ 'has-error': error && errors.email }"> <label for="email">E-mail</label> <input type="email" id="email" class="form-control" placeholder="[email protected]" v-model="email" required> <span class="help-block" v-if="error && errors.email">{{ errors.email }}</span> </div> <div class="form-group" v-bind:class="{ 'has-error': error && errors.password }"> <label for="password">Password</label> <input type="password" id="password" class="form-control" v-model="password" required> <span class="help-block" v-if="error && errors.password">{{ errors.password }}</span> </div> <button type="submit" class="btn btn-default">Submit</button> </form> </div> </template>
Создайте еще один файл с именем Login.vue в том же каталоге и поместите в него следующий код.
<template>
<div>
<div class="alert alert-danger" v-if="error">
<p>There was an error, unable to sign in with those credentials.</p>
</div>
<form autocomplete="off" @submit.prevent="login"
method="post">
<div class="form-group">
<label for="email">E-mail</label>
<input type="email" id="email" class="form-control" placeholder="[email protected]" v-model="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" class="form-control" v-model="password" required>
</div>
<button type="submit" class="btn btn-default">Sign in</button>
</form>
</div>
</template>
Также создайте еще один файл с именем Dashboard.vue в том же каталоге и поместите в него следующий код.
<template>
<h1>Laravel 5 – Our Cool Dashboard</h1>
</template>
Затем замените содержимое файла resources / assets / js / app.js приведенным ниже кодом.
import Vue from 'vue'; import VueRouter from 'vue-router'; import axios from 'axios'; import VueAxios from 'vue-axios'; import App from './App.vue'; import Dashboard from './components/Dashboard.vue'; import Home from './components/Home.vue'; import Register from './components/Register.vue'; import Login from './components/Login.vue'; Vue.use(VueRouter); Vue.use(VueAxios, axios); axios.defaults.baseURL = 'http://localhost:8000/api'; const router = new VueRouter({ routes: [{ path: '/', name: 'home', component: Home },{ path: '/register', name: 'register', component: Register },{ path: '/login', name: 'login', component: Login }] });
@ websanova / vue-auth
Это библиотека, отвечающая за обработку аутентификации на стороне клиента. Он внедряет объект $ auth, который предоставляет несколько вспомогательных функций, таких как register (), который обрабатывает регистрацию пользователя, login (), который обрабатывает логин пользователя, user (), который обеспечивает доступ к текущим данным пользователя, logout () с ручками выхода из системы, и пара других функций.
Установите @ websanova / vue-auth.
npm install @websanova/vue-auth
Измените app.js, чтобы он выглядел как код ниже.
import Vue from 'vue'; import VueRouter from 'vue-router'; import axios from 'axios'; import VueAxios from 'vue-axios'; import App from './App.vue'; import Dashboard from './components/Dashboard.vue'; import Home from './components/Home.vue'; import Register from './components/Register.vue'; import Login from './components/Login.vue'; Vue.use(VueRouter); Vue.use(VueAxios, axios); axios.defaults.baseURL = 'http://localhost:8000/api'; const router = new VueRouter({ routes: [{ path: '/', name: 'home', component: Home },{ path: '/register', name: 'register', component: Register, meta: { auth: false } },{ path: '/login', name: 'login', component: Login, meta: { auth: false } },{ path: '/dashboard', name: 'dashboard', component: Dashboard, meta: { auth: true } }] }); Vue.router = router Vue.use(require('@websanova/vue-auth'), { auth: require('@websanova/vue-auth/drivers/auth/bearer.js'), http: require('@websanova/vue-auth/drivers/http/axios.1.x.js'), router: require('@websanova/vue-auth/drivers/router/vue-router.2.x.js'), }); App.router = Vue.router new Vue(App).$mount('#app');
В приведенный выше код мы включили только что установленную библиотеку и дали ей некоторые настройки для работы.
auth: require(‘@websanova/vue-auth/drivers/auth/bearer.js’)
В приведенной выше строке настраивается vue-auth для использования драйвера носителя, который в основном добавляет токен аутентификации в заголовок нашего запроса во время запросов, а также читает и анализирует токен из ответов нашего сервера.
http: require(‘@websanova/vue-auth/drivers/http/axios.1.x.js’)
Опция выше настраивает vue-auth для использования http-драйвера axios, поскольку мы используем axios для наших http-запросов.
router: require(‘@websanova/vue-auth/drivers/router/vue-router.2.x.js’)
В приведенной выше строке настраивается vue-auth для использования драйвера для vue-router, поскольку это то, что мы используем в нашем приложении.
Мы также добавили в наши маршруты параметр meta.
... meta: { auth: true } ...
Свойство auth указывает, требуется ли авторизация для доступа к маршруту. Итак, мы указали, что для доступа к нашей панели инструментов необходима авторизация; а также указали, что зарегистрированные пользователи не должны иметь доступ к входу в систему и регистрировать маршруты, задав для свойства auth значение false.
Посетите @ websanova / vue-auth, чтобы узнать больше об этой библиотеке.
А теперь беги
npm run watch
и попробуйте получить доступ к панели управления из вашего браузера. Это должно перенаправить вас на страницу входа.
Jwt-auth
В дальнейшем нам нужно будет установить библиотеку jwt-auth в laravel. Это библиотека, которая обрабатывает аутентификацию через наш api.
Чтобы установить, выполните следующую команду на своем терминале.
composer require tymon/jwt-auth
Затем добавьте службу JWTAuthServceProvider в массив поставщиков и фасад JWTAuth в массив псевдонимов в config / app.php
... 'providers' => [ ... Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class, ] ... 'aliases' => [ ... 'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, ]
Опубликуйте конфигурацию.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
Сгенерируйте ключ в опубликованной конфигурации
php artisan jwt:generate
Примечание: если эта ошибка приводит к ошибке, проверьте эту ссылку, чтобы исправить ее.
Отредактируйте app / Http / Kernel.php, добавив jwt.auth и jwt.refresh в массив промежуточного программного обеспечения маршрута приложения.
protected $routeMiddleware = [ ... 'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class, 'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class, ];
Регистрация
Прежде чем мы углубимся в это, давайте создадим контроллер и добавим требуемый маршрут в наш routes / api.php .
Во-первых, давайте создадим контроллер для аутентификации.
php artisan make:controller AuthController
Добавьте маршрут.
Route::post(‘auth/register’, ‘AuthController@register’);
Давайте также создадим FormRequest для обработки проверки для каждого запроса на регистрацию.
php artisan make:request RegisterFormRequest
Давайте отредактируем наш класс RegisterFormRequest, чтобы отразить приведенный ниже код.
... class RegisterFormRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'name' => 'required|string|unique:users', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6|max:10', ]; } }
Давайте теперь создадим метод, который будет обрабатывать регистрацию пользователей в нашем AuthController.
public function register(RegisterFormRequest $request) { $user = new User; $user->email = $request->email; $user->name = $request->name; $user->password = bcrypt($request->password); $user->save(); return response([ 'status' => 'success', 'data' => $user ], 200); }
Класс RegisterFormRequest обеспечивает соответствие каждого запроса правилам, установленным в его методе rules (). Затем метод register () собирает вводимые пользователем данные из переменной $ request, шифрует пароль пользователя и сохраняет данные пользователя в нашей базе данных.
Теперь давайте перейдем к vue и соединим точки. Перейдите в файл Register.vue и добавьте приведенный ниже код в конец файла.
<script> export default { data(){ return { name: '', email: '', password: '', error: false, errors: {}, success: false }; }, methods: { register(){ var app = this this.$auth.register({ data: { name: app.name, email: app.email, password: app.password }, success: function () { app.success = true }, error: function (resp) { app.error = true; app.errors = resp.response.data.errors; }, redirect: null }); } } } </script>
Теперь попробуем зарегистрировать пользователя. Запустить
npm run watch
Зайдите в свой браузер, заполните форму и нажмите «Зарегистрироваться». Если все прошло хорошо, вы сможете зарегистрировать пользователя.
Авторизация
Вернитесь к AuthController и добавьте метод login ().
public function login(Request $request) { $credentials = $request->only('email', 'password'); if ( ! $token = JWTAuth::attempt($credentials)) { return response([ 'status' => 'error', 'error' => 'invalid.credentials', 'msg' => 'Invalid Credentials.' ], 400); } return response([ 'status' => 'success' ]) ->header('Authorization', $token); }
Также добавьте методы user () и refresh ().
public function user(Request $request) { $user = User::find(Auth::user()->id); return response([ 'status' => 'success', 'data' => $user ]); } public function refresh() { return response([ 'status' => 'success' ]); }
user () используется для выборки пользовательских данных, а метод refresh () используется для обновления текущего токена при проверке его допустимости.
Добавьте приведенный ниже код в файл routes / api.php.
Route::post('auth/login', 'AuthController@login'); Route::group(['middleware' => 'jwt.auth'], function(){ Route::get('auth/user', 'AuthController@user'); }); Route::group(['middleware' => 'jwt.refresh'], function(){ Route::get('auth/refresh', 'AuthController@refresh'); });
Давайте подключимся к vue. Перейдите в свой Login.vue и добавьте в файл следующий код.
<script> export default { data(){ return { email: null, password: null, error: false } }, methods: { login(){ var app = this this.$auth.login({ params: { email: app.email, password: app.password }, success: function () {}, error: function () {}, rememberMe: true, redirect: '/dashboard', fetchUser: true, }); }, } } </script>
Это должно сработать. На этом этапе вы сможете войти в систему после запуска
npm run watch
Выйти
Вернемся к нашему AuthController, давайте добавим метод logout ().
public function logout() { JWTAuth::invalidate(); return response([ 'status' => 'success', 'msg' => 'Logged out Successfully.' ], 200); }
Этот метод гарантирует, что пользователь вышел из серверной части нашего приложения, тем самым аннулируя токен аутентификации, который также очищается со стороны клиента.
Давайте также добавим маршрут в наш routes / api.php.
Route::group(['middleware' => 'jwt.auth'], function(){ ... Route::post('auth/logout', 'AuthController@logout'); });
Давайте изменим наш App.vue.
<template> <div class="panel panel-default"> <div class="panel-heading"> <nav> <ul class="list-inline"> <li> <router-link :to="{ name: 'home' }">Home</router-link> </li> <li v-if="!$auth.check()" class="pull-right"> <router-link :to="{ name: 'login' }">Login</router-link> </li> <li v-if="!$auth.check()" class="pull-right"> <router-link :to="{ name: 'register' }">Register</router-link> </li> <li v-if="$auth.check()" class="pull-right"> <a href="#" @click.prevent="$auth.logout()">Logout</a> </li> </ul> </nav> </div> <div class="panel-body"> <router-view></router-view> </div> </div> </template>
$ auth.check () используется, если пользователь вошел в систему, а $ auth.logout () выполняет выход пользователя из системы.
Запустить
npm run watch
и попробуйте. Все должно работать нормально.
Заключение
В этом руководстве мы продемонстрировали, как аутентифицировать запросы api для приложения laravel на основе vue с одной страницей.
Полный исходный код этого руководства можно найти на github.