7

之前我们已经准备好了基本的安装过程 现在我们去实现一下具体的业务部分

用户的登录与注册

对于用户注册 这对于一款应用来说再正常不过了 为了接下来我们的效果 我们可以去生成一个UserController

即在项目终端执行

$ php artisan make:controller App\\Api\\Controllers\UserController

生成用户之后我们暂时先不去编辑字段 后面我们需要用到时再加

返回字段数据沿用之前创建的Lesson Model 这里我们先在routes/api.php加上我们的基本路由

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
    $api->group(['namespace' => 'App\Api\Controllers'], function ($api) {
        $api->get('lessons', 'LessonsController@index');
        $api->get('lessons/{id}', 'LessonsController@show');
    });
});

我们就去访问这个http://host/api/lessons 先去完成控制器的相关方法

public function index()
{
    $lessons =  Lesson::all();
    
    return response()->json($data);
}

这只是简单的返回Lessons的全部字段信息 但是我们可以看到已经返回了所有的字段信息

但是这个时候有个问题就是 我们的字段返回时不可能是全部返回的 我们肯定会对一些字段进行筛选 这就用到了我们之前创建的Transformers这个文件下的了

话不多说 在App/Api/Transformers目录下新建LessonTranformer

use App\Lesson;
use League\Fractal\TransformerAbstract;

class LessonTransformer extends TransformerAbstract
{
    public function transform(Lesson $lesson)
    {
        return [
            'title' => $lesson['title'],
            'content' => $lesson['body'],
            'is_free' => (boolean)$lesson['free']
        ];
    }
}

这样我们就实现了对字段数据的映射 再去LessonController去对之前的所有字段进行映射

public function index()
{
    $lessons =  Lesson::all();

    return $this->collection($lessons,new LessonTransformer());
}

当然这个要想实现这个collection我们需要使用Dingo提供给我们的Helpers trait

这样一来的话我们之前所继承的基类可以这样写

use Dingo\Api\Routing\Helpers;

class Controller extends BaseController
{
    use Helpers,AuthorizesRequests, DispatchesJobs, ValidatesRequests;

}

这样我们返回的就只有title content is_free这三个字段

同样的如果我们想要获取其中一条数据的话 我们也是可以这样去映射字段的

public function show($id)
{
    $lesson = Lesson::find($id);
    if(!$lesson){
        return $this->response()->errorNotFound("Lesson nt found");
    }
    return $this->response()->item($lesson,new LessonTransformer());
}

这里我用的是Dingo提供给的返回方法 如果没有这条数据会返回404和对应的错误信息

下面就是 结合jwt的auth认证
为此我们在App\Api\Controllers目录下新建一个AuthController

这里我们需要去编写我们的认证方法和获取认证用户的方法

新建认证

 public function authenticate(Request $request)
{
    // grab credentials from the request
    $credentials = $request->only('email','password');


    try {
        // attempt to verify the credentials and create a token for the user
        if (! $token = JWTAuth::attempt($credentials)) {
            return response()->json(['error' => 'invalid_credentials'], 401);
        }
    } catch (JWTException $e) {
        // something went wrong whilst attempting to encode the token
        return response()->json(['error' => 'could_not_create_token'], 500);
    }

    // all good so return the token
    return response()->json(compact('token'));
}

为了执行这个方法 可以去路由中定义

$api->version('v1', function ($api) {
    $api->group(['namespace' => 'App\Api\Controllers'], function ($api) {
        $api->post('user/login','AuthController@authenticate');
        $api->post('user/register','AuthController@register');
    });
});

这个时候再去查看一下我们的路由的话就会看到新定义的post路由

为了验证请求的结果 我们可以使用postman这个chrome工具 去请求http://localhost:8000/api/use...

这个时候是会返回{"error":"invalid_credentials"}

为了能够正确通过,我们可以在body部分给出用户邮箱和密码(用户可用thinker创建一个) 这个时候就会正确返回一个token

当然为了测试的话可以直接去tinker新建一个用户即可 这里我已经新建了一个用户邮箱是jellybean@163.com的用户

图片描述

这样我们就可以拿到用户的token 我们在集成jwt认证时 添加了jwt:auth的中间件

这个其实很好理解 就比如一篇文章 如果用户没有登录进来你是不能对文章进行收藏 评论等操作的

那么这个token我们是在用户登录之后或者用户注册之后会返回给客户段一个token值 这样用户凭借这个token

也就是一个证明你是已经登录的用户 你是我们这个网站的用户 这样你就可以发表文章等操作

这样的话我们可以为一些路由添加一些中间件

$api->group(['namespace' => 'App\Api\Controllers','middleware'=>'jwt.auth'],function ($api){
        $api->get('lessons','LessonsController@index');
        $api->get('lessons/{id}','LessonsController@show');
    });

这样的话我们再去访问某一个lesson的话

图片描述

提示我们缺少token 因为现在相当于一个没有登录的用户去访问这条路由 那么我们再去接上我们的token的话

图片描述

这下我们就可以访问到对应的数据了 这个token也是会有过期时间的 如果过期了 我们需要去更新这个token

在应用中我们可以加一个api_token字段来存储这个字段 这样每次用户去访问相应的路由的话我们会去验证这个token

当然 jwt 安装成功后 ,默认使用的 auth 进行 认证 ,读取的也是users表的数据

如果是需要验证其他的数据表的话可以参照这篇文章 jwt 自定义 数据表 区别于 auth 中的 users 表

这样基本就实现了一个基本的后台接口的请求过程

参考我的博客文章


GeekGhc
566 声望71 粉丝

Never underestimate your power to change yourself