上一篇我们简单演示了 Laravel 5.5 中 RESTful API 的构建、认证和测试,本教程将在上一篇教程的基础上进行升华。
我们将结合 Laravel 和 Vue 单页面应用(SPA),在它们的基础上引入 jwt-auth 实现 API 认证,由于 Laravel 集成了对 Vue 的支持,所以在 Laravel 中使用 Vue 也是如鱼得水,非常顺畅,整篇教程涉及到的工具包括:
我们将在上一篇创建应用的基础上进行开发。
首先,在项目根目录下运行以下命令安装前端依赖:
npm install
然后,安装一些必要的 Vue 组件:
npm install --save-dev vue-axios vue-router vue-loader vue-template-compiler
接下来,创建应用所需的 Vue 模板和视图。
在 resources/assets/js 目录下新建 App.vue:
在 resources/assets/js/components 目录下新增 Home.vue:
Laravel 5 Vue SPA 认证
替换 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 内容如下:
Laravel
最后,在项目根目录下运行 npm run watch,就可以在浏览器中通过 http://apidemo.test 访问新首页了。
接下来我们来创建需要的 Vue 组件。
在 resources/assets/js/components 目录下新建 Register.vue:
出错了,很遗憾,未能完成注册
注册完成,你现在可以登录 了
在同一目录下创建 Login.vue:
出错了,请检查邮箱/密码是否正确
最后在该目录下新建 Dashboard.vue:
Laravel 5 – 酷炫的后台
编辑 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://apidemo.test/api';
const router = new VueRouter({
routes: [{
path: '/',
name: 'home',
component: Home
},{
path: '/register',
name: 'register',
component: Register
},{
path: '/login',
name: 'login',
component: Login
}]
});
new Vue({
el: '#app',
router: router,
render: app => app(App)
});
@websanova/vue-auth 是客户端负责处理认证的库,它会注入一个 $auth 对象来提供很多有用的函数:比如 register() 来处理用户注册,login() 来处理用户登录,user() 来访问当前登录用户数据,logout() 来处理退出操作等等。
首先安装这个库:
npm install @websanova/vue-auth
再次编辑 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://apidemo.test/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');
在新增的代码中,我们首先引入了刚刚安装的库并且做了一些配置:
最后,注意到:
meta: {
auth: true
}
该配置用于指定访问路由是否需要认证。
想要了解更多可以访问 @websanova/vue-auth Github 仓库。
重新运行 npm run watch 命令后,访问后台 http://apidemo.test/#/dashboard ,就会自动跳转到登录页面 http://apidemo.test/#/login 。
本教程中,服务器端我们将使用 jwt-auth 来实现 API 认证。
先安装这个扩展包。
composer require tymon/jwt-auth
然后,在配置文件 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"
在发布的配置中生成 key:
php artisan jwt:generate
如果上述命令执行后,出现了如下错误信息:
Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist
可在 vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php 文件中添加如下代码解决:
public function handle() { $this->fire(); }
JWT_SECRET 成功生成后,我们继续配置。
编辑 app/Http/Kernel.php 添加 jwt.auth 和 jwt.refresh 到应用的路由中间件 $routeMiddleware :
protected $routeMiddleware = [
...
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];
接下来,就是添加路由,创建控制器,进行 API 功能验证了。
在 routes/api.php 中,添加用户注册路由。
Route::post('auth/register', 'AuthController@register');
创建认证所需控制器:
php artisan make:controller AuthController
再创建一个 FormRequest 来处理注册请求验证:
php artisan make:request RegisterFormRequest
编辑 app/Http/Requests/RegisterFormRequest.php 文件:
'required|string|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:6|max:10',
];
}
}
接下来,在控制器 AuthController 中创建一个 register 方法:
email = $request->email;
$user->name = $request->name;
$user->password = bcrypt($request->password);
$user->save();
return response([
'status' => 'success',
'data' => $user
], 200);
}
}
然后,在 Register.vue 文件的末尾添加如下代码:
再次运行 npm run watch,然后在浏览器中通过 http://apidemo.test/#/register 访问注册页面进行注册。
回到 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 = auth()->user();
return response([
'status' => 'success',
'data' => $user
]);
}
public function refresh()
{
return response([
'status' => 'success'
]);
}
其中,user() 方法用于获取当前登录用户数据,而 refresh() 方法用于检查当前登录用户 token 是否仍然有效。
当然,还需给上面新增的控制器方法注册路由:
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');
});
最后,将以下代码添加到 Login.vue 末尾:
运行 npm run watch, 进入登录页面 http://apidemo.test/#/login 输入之前注册成功的用户信息进行登录。
登录成功后,页面会跳转到后台 http://apidemo.test/#/dashboard。
添加 logout() 方法到控制器 AuthController:
public function logout()
{
JWTAuth::invalidate();
return response([
'status' => 'success',
'msg' => 'Logged out Successfully.'
], 200);
}
该方法会确保用户从后台退出,从而使 token 失效,进而从客户端清除。
在 routes/api.php 注册对应路由:
Route::group(['middleware' => 'jwt.auth'], function(){
...
Route::post('auth/logout', 'AuthController@logout');
});
然后编辑 App.vue 文件:
$auth.check() 用于检查用户是否登录,$auth.logout() 用于用户退出请求。
运行 npm run watch,刷新 http://apidemo.test/#/dashboard 。点击「退出」按钮,用户退出登录,页面跳转到首页。
至此,我们已经结合 Laravel 5.5 和 Vue SPA ,基于 jwt-auth 实现了 API 基本认证功能。
为了防止大家出错,这里将两个非常重要的文件的代码全部粘贴出来。
app/Http/Controllers/AuthController.php 认证控制器
email = $request->email;
$user->name = $request->name;
$user->password = bcrypt($request->password);
$user->save();
return response([
'status' => 'success',
'data' => $user
], 200);
}
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);
}
public function user(Request $request)
{
$user = auth()->user();
return response([
'status' => 'success',
'data' => $user
]);
}
public function refresh()
{
return response([
'status' => 'success'
]);
}
public function logout()
{
JWTAuth::invalidate();
return response([
'status' => 'success',
'msg' => 'Logged out Successfully.'
], 200);
}
}
routes/api.php 路由文件
'jwt.auth'], function(){
Route::get('auth/user', 'AuthController@user');
Route::post('auth/logout', 'AuthController@logout');
});
Route::group(['middleware' => 'jwt.refresh'], function(){
Route::get('auth/refresh', 'AuthController@refresh');
});
想要了解更多关于 jwt-auth 的信息,请访问 http://jwt-auth.readthedocs.io/en/develop/ 。
下一篇我们来讲解如何将 Laravel 5.5 新增的 Eloquent API Resource 功能集成进来。