我們瞭解了 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 生成器》mp.weixin.qq.com/s/mRjoKgkq1…,主要是想利用 jwt
和 GraphQL
作為介面層,為之後的前端開發,提供資料基礎。
主要參考:
- 學習 Lumen 使用者認證 (二) —— 使用 jwt-auth 外掛 mp.weixin.qq.com/s/k1v-mji7Y…
- 推薦一個 Laravel admin 後臺管理外掛 mp.weixin.qq.com/s/PnAj0j2X3…
- 結合 Laravel 初步學習 GraphQL mp.weixin.qq.com/s/Uvv4X9hXT…
原始碼
「未完待續」