GraphQL 配合 JWT 使用 —— Laravel RSS

Posted coding01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GraphQL 配合 JWT 使用 —— Laravel RSS 相关的知识,希望对你有一定的参考价值。

本文字数:7025,大概需要 14.05 分钟。

我们了解了 jwt  GraphQL 的使用,那接下来看看他们如何结合使用。

小试牛刀

创建 myProfile query

<?php
/**
* User: yemeishu
* Date: 2018/4/21
* Time: 上午8:55
*/


namespace App\GraphQL\Query;

use App\User;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;
use Rebing\GraphQL\Support\SelectFields;
use Tymon\JWTAuth\Facades\JWTAuth;

class MyProfileQuery extends Query {
   private $auth;

   protected $attributes = [
       'name' => 'My Profile Query',
       'description' => 'My Profile Information'
   ];

   public function authorize(array $args) {
       try {
           $this->auth = JWTAuth::parseToken()->authenticate();
       } catch (\Exception $e) {
           $this->auth = null;
       }

       return (boolean) $this->auth;
   }

   public function type() {
       return GraphQL::type('myprofile');
   }

   public function resolve($root, $args, SelectFields $fields) {
       $user = User::with(array_keys($fields->getRelations()))
           ->where('id', $this->auth->id)
           ->select($fields->getSelect())->first();

       return $user;
   }

}

创建 Type

<?php
/**
* User: yemeishu
* Date: 2018/4/21
* Time: 下午3:59
*/


namespace App\GraphQL\Type;

use App\User;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;

class MyProfileType extends GraphQLType
{
   protected $attributes = [
       'name' => 'myprofile',
       'description' => 'A type',
       'model' => User::class, // define model for users type
   ];

   // define field of type
   public function fields()
   
{
       return [
           'id' => [
               'type' => Type::nonNull(Type::int()),
               'description' => 'The id of the user'
           ],
           'email' => [
               'type' => Type::string(),
               'description' => 'The email of user'
           ],
           'name' => [
               'type' => Type::string(),
               'description' => 'The name of the user'
           ]
       ];
   }

   protected function resolveEmailField($root, $args)
   
{
       return strtolower($root->email);
   }
}

注册 GraphQL config

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

当然要获取 jwt token,需要有一个 login 方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\JWTAuth;

class AuthenticateController extends Controller {
   private $jwt;

   public function __construct(JWTAuth $jwt) {
       $this->jwt = $jwt;
   }

   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 = $this->jwt->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'));
   }
}

注册路由:

Route::post('/login', 'AuthenticateController@authenticate');

先利用 email 和 password 获得 token 值:

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

然后利用 token 获取用户信息:

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

获取 Xpath List

在 RSS 系统中,我们也希望给每个用户创建自己的 RSS Feeds。所以先修改 xpath 的归属。

php artisan make:migration add_user_id_to_xpaths_table --table=xpaths
public function up() {
   Schema::table('xpaths', function (Blueprint $table) {
       $table->integer('user_id')->unsigned();
   });
}

admin 添加 xpath 归属操作

 XpathController  form 函数增加 user_id 的选择框:

$form->select('user_id')->options(function ($id) {
   $user = User::find($id);
   if ($user) {
       return [$user->id => $user->name];
   }
})->ajax('/admin/users');

添加 admin/users route 和 controller

<?php

namespace App\Admin\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller {

   public function users(Request $request) {
       $q = $request->get('q');
       return User::where('name', 'like', "%$q%")
           ->paginate(null, ['id', 'name as text']);
   }
}

这样就可以根据输入的 user name 来选择这个 xpath 的归属。

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

 xpath 列表显示 user_id 值.

首先增加 一对一 关联:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Xpath extends Model
{
   public function user() {
       return $this->belongsTo(User::class);
   }
}

再在 XpathController  grid() 直接增加 user's name:

$grid->column('user.name', '归属人');

显示效果:

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

利用 GraphQL 获取 Xpath 列表

1. 创建 Query

<?php
/**
* User: yemeishu
* Date: 2018/4/21
* Time: 下午11:16
*/


namespace App\GraphQL\Query;

use App\Xpath;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;
use Rebing\GraphQL\Support\SelectFields;
use Tymon\JWTAuth\Facades\JWTAuth;

class MyXpathsQuery extends Query {
   private $auth;

   protected $attributes = [
       'name' => 'My Xpaths Query',
       'description' => 'My Xpaths Information'
   ];

   public function authorize(array $args) {
       try {
           $this->auth = JWTAuth::parseToken()->authenticate();
       } catch (\Exception $e) {
           $this->auth = null;
       }

       return (boolean) $this->auth;
   }

   public function type() {
       return Type::listOf(GraphQL::type('myxpath'));
   }

   public function resolve($root, $args, SelectFields $fields) {
       $xpaths = Xpath::with(array_keys($fields->getRelations()))
           ->where('user_id', $this->auth->id)
           ->select($fields->getSelect())
           ->get();

       return $xpaths;
   }
}

利用 jwt token 获取 user's id,然后再查询属于该用户的 xpath 列表

2. 定义返回的 Type

 <?php
/**
* User: yemeishu
* Date: 2018/4/21
* Time: 下午3:59
*/


namespace App\GraphQL\Type;

use App\User;
use App\Xpath;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;

class MyXpathType extends GraphQLType
{
   protected $attributes = [
       'name' => 'myxpath',
       'description' => 'A type',
       'model' => Xpath::class, // define model for xpath type
   ];

   // define field of type
   public function fields()
   
{
       return [
           'id' => [
               'type' => Type::nonNull(Type::int()),
               'description' => 'The id of the user'
           ],
           'url' => [
               'type' => Type::string(),
               'description' => 'The url of xpath'
           ],
           'urldesc' => [
               'type' => Type::string(),
               'description' => 'The desc of the xpath'
           ]
       ];
   }
}

3. 注册 GraphQL config

GraphQL 配合 JWT 使用 —— Laravel RSS (二)

4. 测试

结果自然显而易见:

总结

这是继续上一篇《花 2 小时撸一个 RSS 生成器》,主要是想利用 jwt  GraphQL 作为接口层,为之后的前端开发,提供数据基础。

主要参考:

  • 学习 Lumen 用户认证 (二) —— 使用 jwt-auth 插件 

  • 推荐一个 Laravel admin 后台管理插件 

  • 结合 Laravel 初步学习 GraphQL 

源代码

https://github.com/fanly/lrss

「未完待续」


coding01 期待您继续关注


以上是关于GraphQL 配合 JWT 使用 —— Laravel RSS 的主要内容,如果未能解决你的问题,请参考以下文章

使用 GraphQL 和 jwt-express 绕过 JWT

不允许使用 JWT 令牌保护 GraphQL 端点

使用 flask-jwt-extended + ariadne (graphql) + react 设置身份验证/授权

如何结合突变在 django-graphql-jwt 中创建或登录用户?

用户注册的 GraphQL 突变不适用于 jwt

django-graphql-jwt JWT_COOKIE_SAMESITE 不工作