Dingo + Laravel + JWT + Entrust + memcache 實現API設計

Dingo + Laravel + JWT + Entrust + memcache 實現API設計

Dingo Api 是一個爲laravel設計的用於API開發的開源包,規範和簡化了Api的設計

JWT 即 Json Web Token,是一種新的用於API認證方式,區別於傳統的Session和Cookie方式,便於攜帶而且比較安全,因爲token只設計爲單次請求

Entrust 是一套基於角色的權限管理系統,用於分層系統設計

Memcache 是一個NoSQL存儲系統,使用鍵值對將數據存儲在內存中,實現快速訪問

DingoApi 安裝及使用

https://github.com/dingo/api

  1. 安裝
//項目基本目錄下執行
composer require dingo/api:1.0.x@dev
//config/app.php
'providers' => [
    Dingo\Api\Provider\LaravelServiceProvider::class
]
//發佈配置文件
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
  1. 配置
//配置可以卸載.env文件中或者config/api.php
API_STANDARDS_TREE=vnd //api 標準
API_SUBTYPE=myapp  //項目短名稱
API_PREFIX=api
API_DOMAIN=api.myapp.com   //這裏記住API_PREFIX或者API_DOMAIN通知只能配置一個,或的關係,訪問的時候通過 http://127.0.0.1:8000/api/your_route 或者 http://api.myapp.com/your_route
API_VERSION=v1
API_NAME="My API" //在.env文件中一定要注意不能有多餘的空格,負責出現莫名的錯誤,如果寫成API_NAME=My API就會出錯
API_CONDITIONAL_REQUEST=false 
API_STRICT=false //如果配置爲真,將需要在每次訪問api是添加Accept頭:application/vnd.myapp.v1+json
API_DEFAULT_FORMAT=json //api返回格式
API_DEBUG=true //API調試
  1. 認證方式

認證方式我們採用JWT方式,關於JWT可以自行谷歌,其他的配置請參考dingo/api 文檔

'auth' => [
        'jwt' => 'Dingo\Api\Auth\Provider\JWT',
    ],

JWT認證方式

https://github.com/tymondesigns/jwt-auth

  1. 安裝
composer require "tymon/jwt-auth:0.5.*"
//添加服務
'Tymon\JWTAuth\Providers\JWTAuthServiceProvider'
//添加alias
JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth'
//發佈配置文件
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
//生成jwt:key
php artisan jwt:generate
  1. 配置,請參考文檔,沒什麼好說的
  2. 創建token

token可以基於任何傳入的數據創建,不過我們一般使用從用戶創建token,如:

$user = User::first();

$token = JWTAuth::fromUser($user);

這裏具體的流程是,用戶提交認證數據,然後根據提交數據查詢用戶,得到用戶以後創建token,這裏貼一段我的代碼

public function signIn(Request $request)
    {
        $info = (new SignInForm())->load($request, 'sign-in');
        if($info instanceof Response)
        {
            return $info;
        }

        $user = null;

        if(Auth::attempt(['nick_name' => $request->input('identity'), 'password' => $request->input('password'), 'status' => User::STATUS_NORMAL])
           || Auth::attempt(['email' => $request->input('identity'), 'password' => $request->input('password'), 'status' => User::STATUS_NORMAL])
           || Auth::attempt(['mobile' => $request->input('identity'), 'password' => $request->input('password'), 'status' => User::STATUS_NORMAL] ))
        {
            $user = Auth::user();
        }

       if($user)
       {
           $token = JWTAuth::fromUser($user);
       } else {
           return ApiResponse::apiResponse(ResponseCode::SIGN_IN_FAILED);
       }

        return ApiResponse::apiResponse(ResponseCode::SIGN_IN_OK, [
            'token' => $token
        ], 0);
    }

客戶端在收到token以後,在需要認證api中加入Authorization頭: Authorization:Bearer {token},我們在dingo/api中配值了API使用jwt認證,所以我們在我們的路由中添加jwt中間件:

//routes.php
<?php

//這裏使用的web組中間件中,我只是開啓了session,其他的都已經註釋掉了,尤其是CSRF中間件應該去掉,否則每次還要提交CSRF值,也可以單獨設置session
// 'web' => [
//             //\App\Http\Middleware\EncryptCookies::class,
//             //\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
//             \Illuminate\Session\Middleware\StartSession::class,
//             //\Illuminate\View\Middleware\ShareErrorsFromSession::class,
//             //\App\Http\Middleware\VerifyCsrfToken::class,
//         ],

$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api){

    $api->group(['namespace' => 'App\Http\Controllers\V1', 'middleware' => ['web']], function ($api){

        $api->post('sign-up', ['as' => 'user.signUp', 'uses' => 'AppController@signUp']);
        $api->post('sign-in', ['as' => 'user.signIn', 'uses' => 'AppController@signIn']);
        $api->post('third-auth', ['as' => 'user.thirdAuth', 'uses' => 'AppController@thirdAuth']);
        $api->post('password-reset/send-verify-code', 'PasswordController@sendResetPasswordEmail');
        $api->post('password-reset/set-new-password', 'PasswordController@resetNewPassword');

        $api->group(['middleware' => 'api.auth'], function ($api){

            $api->group(['middleware' => ['before' => 'jwt.auth']], function ($api){

                $api->group(['middleware' => ['after' => 'jwt.refresh']], function ($api){

                    //用戶資源
                    $api->resource('user', 'UserController', [
                        'only' => ['show', ],
                        'names' => [
                            'show' => 'user.show',
                        ],
                    ]);

                    //用戶資料資源
                    $api->resource('profile', 'ProfileController', [
                        'only' => ['show', ],
                        'names' => [
                            'show' => 'profile.show'
                        ],
                    ]);

                });

                $api->get('logout', ['as' => 'user.logout', 'uses' => 'AppController@logout']);
                $api->get('refresh-token', ['as' => 'user.refreshToken', 'uses' => 'AppController@refreshToken']);
            });
        });

    });
});

api.auth中間件不要配置,只是說明路由是保護路由;

jwt.auth 需要配置,配置請看文檔,會在api請求處理之前檢查用戶是否已經認證,主要是驗證Authorization頭部信息;

jwt.refresh 會在訪問成功之後,刷新token,並附加在響應頭部的Authorization頭部中;但是這個中間件應該只能用於需連續訪問的API中,像logout和refresh-token就不需要刷新。
說到刷新token,如果大家瞭解jwt認證機制,應該明白token只能用於單次請求,請求成功之後失效,不過可以通過這個舊的token刷新得到新的token;
因此這裏要啓用黑名單功能,將失效的token寫入黑名單。黑名單十一緩存的形式存在,根據應用緩存的配置,寫入文件或者數據庫或者其他形式,如果是寫入文件,你的storage目錄應該要具有可寫權限;

需要提醒的是緩存形式配置爲file時,entrust不能正常使用,此問題需等待新版本修復。折中的辦法是你可以將緩存設置memcached,就不會出現問題了

entrust

https://github.com/Zizaco/entrust

關於entrust本人覺得除了緩存配置比較坑意外,其他應該都能看得懂,有問題請留言

ubuntu memcached 服務器以及PHP擴展庫安裝:

  1. memcached 服務器安裝
//方法一:
sudo apt-get install memcached
//方法二(編譯安裝):
wget http://memcached.org/files/memcached-1.4.25.tar.gz
tar xzvf memcached-1.4.25.tar.gz
cd memcached-1.4.25
./configure && make && make test && sudo make install
//最後測試
memcached -d -m 50 -p 11211 -u root
-m 指定使用多少兆的緩存空間;-p 指定要監聽的端口; -u 指定以哪個用戶來運行 -d 以系統進程運行,也就是作爲系統服務
  1. 安裝libmmecached
wget https://launchpad.net/libmemcached/1.0/0.51/+download/libmemcached-0.51.tar.gz
tar xzvf libmemcached-0.51.tar.gz
cd libmemcached-0.51
 ./configure  --prefix=/usr/local/libmemcached --with-memcached
sudo make && sudo make install
  1. 安裝memcached擴展庫
//安裝之前可能要求安裝pkg-config
sudo apt-get install phk-config
wget http://pecl.php.net/get/memcached-2.2.0.tgz
tar xzvf memcached-2.2.0.tgz
cd memcached-2.2.0
phpize5
/configure  --with-php-config=/usr/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached --disable-memcached-sasl
sudo make && sudo make install
  1. memadmin memcached監控工具
    https://github.com/junstor/memadmin

需要PHPmemcache擴展

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章