API 認證系統 Passport

安裝

composer require laravel/passport=~4.0

notes:
1)確保系統安裝unzip蔽午、zip等命令。
2)composer 安裝出現 Authentication required (packagist.phpcomposer.com) 問題酬蹋,修改composer.json 中的源及老,repositories.packagist.url = https://packagist.laravel-china.org

注冊服務提供者

在config/app.php的providers 數組中加入 Laravel\Passport\PassportServiceProvider::class

遷移數據庫

php artisan migrate  //生成用于存儲客戶端和令牌的數據表

生成加密健

 php artisan passport:install  

1范抓、生成oauth-private.key(用于構建認證服務器)骄恶,oauth-public.key(用于構建資源服務器)
2、oauth_clients數據庫生成「個人訪問」客戶端和「密碼授權]兩條數據匕垫。

配置Passport(參考官方文檔)

在Model中僧鲁,我們需要增加 HasApiTokens class
在AuthServiceProvider中, 增加 "Passport::routes()"
在 auth.php中, 更改 api 認證方式為passport

申請客戶端以及私人訪問令牌 (兩種方式)

1. 命令形式(不方便客戶注冊)
php artisan passport:client
8.jpg
2. Passport Vue 組件
php artisan vendor:publish --tag=passport-components  //發(fā)布 Passport Vue寞秃,組件位于resources/assets/js/components下

//注冊到resources/assets/js/app.js 文件斟叼,記得要放在new Vue上面

Vue.component(
    'passport-clients',
    require('./components/passport/Clients.vue')
);

Vue.component(
    'passport-authorized-clients',
    require('./components/passport/AuthorizedClients.vue')
);

Vue.component(
    'passport-personal-access-tokens',
    require('./components/passport/PersonalAccessTokens.vue')
);

//編譯前端資源

npm install   //此處報錯,移步larravel Mix文檔
npm run dev

編譯后資源放在public/js/app.js下

//組件放入應用模板(記得引入編譯后的app.js)

<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
9.jpg

以上認證服務器都已經搭建完成

第三方應用實現登錄

1. 申請客戶端

10.jpg

回調地址 http://third.plat.goods/dew/sso

申請授權碼和訪問令牌

//獲取授權碼 code (第一次交互)

$query = http_build_query(array(
        'client_id' => 3,
        'redirect_uri' => 'http://third.plat.goods/dew/sso', //地址必須為上面的回調地址
        'response_type' => 'code',  //固定值
        'scope' => '',
        'state' => urlencode('http://laravel.plat.goods/user')   //可以放用戶訪問的地址春寿。
));

return redirect('http://laravel.plat.goods/oauth/authorize?'.$query);  ///laravel.plat.goods為上面認證服務器
11.jpg

//獲取訪問令牌 access token 以及向資源服務器請求用戶信息
授權后會重定向回調地址

Route::get('/dew/sso', 'SSOController@callback');  //路由文件里添加
php artisan make:controller SSOController //創(chuàng)建文件
<?php
namespace App\Http\Controllers;

use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class SSOController extends Controller
{
    protected $http;
    public function __construct()
    {
        $this->http = new Client();
    }

    /**
     * 獲取授權碼后的回調URL
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function callback(Request $request)
    {

        $token = $this->token($request); //第二次交互
        $login = $this->login($token);//第三次交互

        if($login){

            if($request_url = $request->input('state', null)){
                $request->session()->put('url.intended', urldecode($request_url));
            }
            return redirect()->intended();  //跳轉到 http://laravel.plat.goods/user
        }else{
            return redirect()->to('http://laravel.plat.com/home/public/login'); //服務提供商網站必須登錄
        }
    }

    /**
     * 獲取access token
     * @param $request
     * @return array|mixed
     */
    protected function token($request)
    {
        $code = $request->code;
        if($code) {

            try {

                $response = $this->http->post('http://laravel.plat.goods/oauth/token', [
                    'form_params' => [
                        'grant_type' => 'authorization_code',  //固定值
                        'client_id' => 3,
                        'client_secret' => 'UihXNHoSqohdtQ8Js6Av7AOyk3GBNB9rJziDPaWf',
                        'redirect_uri' => 'http://third.plat.goods/dew/sso',
                        'code' => $code,
                    ],
                ]);

                $response_data = json_decode((string)$response->getBody(), true);

                return $response_data;
            } catch (\Exception $e) {

                Log::error('get token by code failed: '.$code.' - '.$e->getMessage().' - '.$e->getTraceAsString());

                return [];
            }
        }else{

            return [];
        }

    }
    /**
     * 通過token獲取用戶信息犁柜,并進行登錄操作
     * @param $token
     * @return bool
     */
    protected function login($token)
    {
        if(empty($token)) return false;

        $access_token = $token['access_token'];
        try {
           
           // 資源服務器和認證服務器放在了一起,可以獨立堂淡。
            $response = $this->http->request('GET', 'http://laravel.plat.goods/api/user', [
                'headers' => [
                    'Accept' => 'application/json',
                    'Authorization' => $token['token_type'] . ' ' . $access_token,
                ]
            ]);
            $users_body = $response->getBody();
            $data = json_decode($users_body, true);
            if($data) {
                $user = new User($data);

                //because of employee_id is guarded
                $user->setAttribute($user->getKeyName(), $data['employee_id']);
                //login user in my system
                auth()->login($user, false);

                return true;
            }else{

                return false;
            }
        }catch (\Exception $e){

            Log::error('get user failed by access_token:'.$access_token.'|'.$e->getMessage());
            return false;
        }
    }
}

//設置資源文件

Route::middleware('auth:api')->get('/user', 'UserController@user'); //routes/api.php文件中設置
php artisan make:controller UserController //創(chuàng)建文件
class UserController extends Controller
{
    public function user(Request $request)
    {
        return $request->user();
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末馋缅,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子绢淀,更是在濱河造成了極大的恐慌萤悴,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皆的,死亡現場離奇詭異覆履,居然都是意外死亡,警方通過查閱死者的電腦和手機费薄,發(fā)現死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門硝全,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人楞抡,你說我怎么就攤上這事伟众。” “怎么了召廷?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵凳厢,是天一觀的道長。 經常有香客問我竞慢,道長先紫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任筹煮,我火速辦了婚禮遮精,結果婚禮上,老公的妹妹穿的比我還像新娘败潦。我一直安慰自己本冲,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布变屁。 她就那樣靜靜地躺著眼俊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粟关。 梳的紋絲不亂的頭發(fā)上疮胖,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天环戈,我揣著相機與錄音,去河邊找鬼澎灸。 笑死院塞,一個胖子當著我的面吹牛,可吹牛的內容都是我干的性昭。 我是一名探鬼主播拦止,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糜颠!你這毒婦竟也來了汹族?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤其兴,失蹤者是張志新(化名)和其女友劉穎顶瞒,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體元旬,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡榴徐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了匀归。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坑资。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖穆端,靈堂內的尸體忽然破棺而出袱贮,到底是詐尸還是另有隱情,我是刑警寧澤徙赢,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布字柠,位于F島的核電站,受9級特大地震影響狡赐,放射性物質發(fā)生泄漏。R本人自食惡果不足惜钦幔,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一枕屉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸违霞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祭钉。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間威恼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留箫措,地道東北人腹备。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像斤蔓,于是被迫代替她去往敵國和親植酥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容