netcasper 2019-06-27
我们了解了 jwt
和 GraphQL
的使用,那接下来看看他们如何结合使用。
<?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; } }
<?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); } }
当然要获取 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 值:
然后利用 token 获取用户信息:
在 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(); }); }
在 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 的归属。
让 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', '归属人');
显示效果:
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
4. 测试
结果自然显而易见:
这是继续上一篇《花 2 小时撸一个 RSS 生成器》https://mp.weixin.qq.com/s/mRjoKgkq1PoqlVgOw8oRYw,主要是想利用 jwt
和 GraphQL
作为接口层,为之后的前端开发,提供数据基础。
主要参考:
- 学习 Lumen 用户认证 (二) —— 使用 jwt-auth 插件 https://mp.weixin.qq.com/s/k1v-mji7YyilEBoLTw8Dig
- 推荐一个 Laravel admin 后台管理插件 https://mp.weixin.qq.com/s/PnAj0j2X3-lq3Mn06qjIdQ
- 结合 Laravel 初步学习 GraphQL https://mp.weixin.qq.com/s/Uvv4X9hXT8No1MjNlCPqXg
源代码
「未完待续」