我们了解了 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
当然要获取 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 获取用户信息:
获取 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 的归属。
让 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 获取 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
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
源代码
「未完待续」
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。