laravel 开发RestFul接口【二、集成三方扩展 - jwt】

上一篇讲解了如何集成dingo api
在web开发中通常是使用session 来保持会话,在app接口开发中则是用携带token来保持会话!这里涉及到一个常见的面试题,如果客户端禁掉cookie,session 是否有用?
答案:肯定的! 只要你有办法带上自己sessionid 去服务端验证都是可以达到同样多的效果
在开发api也是同样只不过稍微麻烦一点需要自己来实现这么一套会话机制
文中第八点具体讲解遇到一些问题如何处理请细心看下去哦
接下来用jwt来实现认证
1、安装jwt

composer require tymon/jwt-auth 0.5.*

2、加入服务 在config/app 的providers中添加

Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,

3、添加门面(可以理解为别名)在config/app 的aliases中添加

'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,

4、生成jwt 的配置文件

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

5、生成JWT_SECRET

php artisan jwt:generate

6、开发登入注册接口 初始化数据库这里我用已经提供好的users表,方法就不赘述了
添加如下接口 待会会用到

$api = app('Dingo\Api\Routing\Router');

// 配置api版本和路由
$api->version('v1', ['namespace' => 'App\Http\Controllers\Api\V1\Controller'], function ($api) {
    $api->group(['middleware' => ['jwt.api.auth','jwt.refresh'], 'providers' => 'jwt'], function ($api) {
        $api->post("testAuth", 'UserController@testAuth');

    });
        $api->post("reg", 'UserController@reg');
        $api->post("login", 'UserController@login');

    $api->get("test/{id}/{name}", 'RestFulController@test')->name("getinfo");

});

创建User控制器

<?php

namespace App\Http\Controllers\Api\V1\Controller;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Dingo\Api\Routing\Helpers;
use App\User;
use Tymon\JWTAuth\Facades\JWTAuth;
class UserController extends Controller
{
    //
    use Helpers;
    public function reg(Request $request){
        $data = $request->all();

        $res = User::create([
            'nikename' => $data['nikename'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);

        $token = JWTAuth::fromUser($res);
        return $this->response->array($token);
    }

    public function login(Request $request){
        $credentials = $request->only('nikename', 'password');
        try {
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }
        $user = User::where('nikename', $credentials['nikename'])->first()->toArray();

        return ['user'=> $user, 'token' => $token];
    }

    public function testAuth(){
        return $this->response->array(['content'=>'验证成功']);
    }
}

接下来使用postman在测试注册接口
这里写图片描述
可以得到token 就说明成功了
下面测试登入接口
这里写图片描述
返回了用户信息和token
注意上面的的登入注册路由放在了认证组的外面
得到token以后就是认证了
测试testAuth接口
这里写图片描述
验证成功
注意这里的使用携带Authorization头信息去验证 加了Bearer 的前缀标示使用Bearer 的验证方式
我在这一步遇到了很多坑
为了让错误信息更加直观,我们需要自己定义一个验证的中间如下:

<?php

namespace App\Http\Middleware;

use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
class GetUserFromToken
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        try {

            if (! $user = JWTAuth::parseToken()->authenticate()) {
                return response()->json([
                    'errcode' => 400004,
                    'errmsg' => 'user not found'
                ], 404);
            }

        } catch (TokenExpiredException $e) {

            return response()->json([
                'errcode' => 400001,
                'errmsg' => 'token expired'
            ], $e->getStatusCode());

        } catch (TokenInvalidException $e) {

            return response()->json([
                'errcode' => 400003,
                'errmsg' => 'token invalid'
            ], $e->getStatusCode());

        } catch (JWTException $e) {

            return response()->json([
                'errcode' => 400002,
                'errmsg' => 'token absent'
            ], $e->getStatusCode());

        }
        return $next($request);

    }
}

在app/kernel文件中的$routeMiddleware里中注册一个中间件

'jwt.api.auth' => \App\Http\Middleware\GetUserFromToken::class, //新增注册的中间件

接着在路由web.php文件中修改 使用自己定义的中间件来验证····

'middleware' => ['jwt.api.auth','jwt.refresh'], 

7.获取用户信息 修改之前的权限测试代码加上返回信息

 public function testAuth(Request $request){
        if (!$user = JWTAuth::parseToken()->authenticate()) {
            return response()->json(['user_not_found'], 404);
        }
        return $this->response->array(['content'=>'验证成功','token'=>$user]);
    }

这里写图片描述
好的验证成功!!!!!!!!!!!!

8.坑点

  1. 使用Authorization进行验证会抛出 token absent 这个 异常
    按照官方文档上的说法是在apache的http.conf中加入
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

并且#LoadModule rewrite_module modules/mod_rewrite.so这一行去掉#号
另外你也可以使用url来传递token
入xxx.com?token = xxxxxxxxxxxxxxxx.xxxxxx.xxxxxxxxx

 2.登入和注册能正常获得token但是验证的时候会抛出user not found异常····`这里写代码片`

这个就坑了,花了我一个早上的时间终于到stackoverflow找到答案
原因就是你的token 刷新后就直接进黑名单了,应该是我这个版本的一个bug 如何解决呢?
没办法只能进jwt.php 这个配置文件把黑名单关闭了
设为false就可以了

 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', false),

下面放几个链接 希望对大家解决问题有所帮助

https://stackoverflow.com/questions/37051801/laravel-5-2-jwt-user-not-found
http://blog.qiji.tech/archives/16054
http://blog.csdn.net/zzw6236056/article/details/69218486
https://www.cnblogs.com/zaixiuxing/p/6005968.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值