laravel5.7 前后端分离开发 实现基于API请求的token认证 第一步:用户表添加api_token字段 第二步、添加认证服务方 第三步、给用户模型添加生成api_token方法 第四步、在控制器中添加登录方法 第五步、给路由添加认证中间件  第六步、退出时清除 token

https://blog.csdn.net/wei_yalin/article/details/86559513

最近在学习前后端分离开发,发现 在laravel中实现前后台分离是无法无法使用 CSRF Token 认证的。因为 web 请求的用户认证是通过Session和客户端Cookie的实现的,而前后端分离的应用无法通过API请求将Cookie CSRF Token 从前端传递到后端,但是还有一种解决方法,就是使用laravel自带的 API token认证。

1、可以通过数据迁移的方式添加,像这样:

 php artisan make:migration --table=用户表名 add_api_token

 然后编写这个迁移文件,文件位于 database/migration 

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

  1. class AddApiToken extends Migration
  2. {
  3. /**
  4. * Run the migrations.
  5. *
  6. * @return void
  7. */
  8. public function up()
  9. {
  10. Schema::table('用户表名', function (Blueprint $table) {
  11. $table->string('api_token', 200)->unique()->nullable();
  12. });
  13. }
  14. /**
  15. * Reverse the migrations.
  16. *
  17. * @return void
  18. */
  19. public function down()
  20. {
  21. Schema::table('用户表名', function (Blueprint $table) {
  22. $table->dropColumn(['api_token']);
  23. });
  24. }
  25. }

然后执行迁移命令

php artisan migrate

2、或者像我这样,直接在数据库用户表中添加,O(∩_∩)O哈哈~

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

因为 varchar 存储的是变长数据,也就是数据的真实长度,所以不要吝啬可以给长度设大点。

第二步、添加认证服务方

我是多表认证,每个用户角色有一张表,所以需要添加认证服务方,在 config/auth.php 中添加。一般使用已经默认的 api 认证方就好,

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

第三步、给用户模型添加生成api_token方法

  1. /**
  2. * 更新token
  3. * @return mixed|string
  4. */
  5. public function generateToken() {
  6. $this->api_token = str_random(128);
  7. $this->save();
  8. return $this->api_token;
  9. }

第四步、在控制器中添加登录方法

这是我的登录认证,是基于多表的用户认证,我是个小菜菜,细节就不给你们看了,怕你们喷我⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄。总之是在登陆验证成功之后,生成api_token并返回就可以了。

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

第五步、给路由添加认证中间件

api.php 添加如下路由,login 不需要守卫,给 logout 和 其他需要认证的路由添加守卫就可以了(auth:admin , 对应上面的admin用户

  1. Route::any('unAuth', function () {
  2. return responseToJson(1,'未认证或认证失败');
  3. })->name('unAuth');
  4. Route::prefix('admin')->namespace('Admin')->group(function() {
  5. Route::post('login', 'LoginController@login');
  6. Route::middleware('auth:admin')->group(function() {
  7. Route::post('logout', 'LoginController@logout');
  8. Route::get('getMenu', 'MenuController@getMenu');
  9. });
  10. });

laravel5.7 前后端分离开发 实现基于API请求的token认证
第一步:用户表添加api_token字段
第二步、添加认证服务方
第三步、给用户模型添加生成api_token方法
第四步、在控制器中添加登录方法
第五步、给路由添加认证中间件
 第六步、退出时清除 token

使用的是auth中间件,默认的路由我没有O(∩_∩)O,所以需要进行修改。

修改中间件 Authenticate.php , 位于 app/Http/Middleware/Authenticate.php 。

  1. class Authenticate extends Middleware
  2. {
  3. /**
  4. * Get the path the user should be redirected to when they are not authenticated.
  5. *
  6. * @param IlluminateHttpRequest $request
  7. * @return string
  8. */
  9. protected function redirectTo($request)
  10. {
  11. if (! $request->expectsJson()) {
  12. return route('unAuth');
  13. }
  14. }
  15. }

现在就已经好了,在登陆之后会返回 api_token ,然后请求其他路由的时候把 api_token 当参数传过来。这样当请求需要认证的路由的时候如果没有 api_token 或者  api_token 错误,就会跳转到 unAuth 路由,然后返回定义好的提示信息。

 第六步、退出时清除 token

  1. public function logout()
  2. {
  3. $user = Auth::guard('admin')->user();
  4. if ($user) {
  5. $user->api_token = null;
  6. $user->save();
  7. }
  8. return responseToJson(0,'退出成功');
  9. }

还可以写个中间件,每隔一段时间更新一下 api_token 值,同时前端也要更新 api_token 。我写的也不是多好,可以看一下

  1. /**
  2. * Handle an incoming request.
  3. *
  4. * @param IlluminateHttpRequest $request
  5. * @param Closure $next
  6. * @param string|null $guard
  7. * @return mixed
  8. */
  9. public function handle($request, Closure $next, $guard)
  10. {
  11. $response = $next($request);
  12. //验证token是否过期
  13. $user = Auth::guard($guard)->user();
  14. if (isTimeGreater($user->updated_token_at)){
  15. $response->header("api_token", $user->generateToken());
  16. }
  17. return $response;
  18. }