知識(shí)點(diǎn)概括
環(huán)境介紹
- 使用 laradock 作為 laravel 的開(kāi)發(fā)環(huán)境
PHP 7.2溜哮、MySQL 5.7
- Node 環(huán)境
node 9.8屿良、npm 5.6
項(xiàng)目架構(gòu)
- Server 項(xiàng)目用于搭建 驗(yàn)證授權(quán)服務(wù)器
- Client 項(xiàng)目用于 第三方應(yīng)用
設(shè)計(jì)邏輯
實(shí)現(xiàn)類(lèi)似與微信授權(quán)登陸的邏輯。
擋在微信中進(jìn)入其它網(wǎng)頁(yè)時(shí)霉涨,會(huì)出現(xiàn)類(lèi)似授權(quán)的頁(yè)面按价,當(dāng)點(diǎn)擊授權(quán)后即可獲取用戶(hù)的信息。
Server 項(xiàng)目搭建
- 首先使用命令創(chuàng)建 Server 項(xiàng)目
composer create-project laravel/laravel --prefer-dist server
- 配置數(shù)據(jù)庫(kù)
# .env
...
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=server
DB_USERNAME=root
DB_PASSWORD=root
...
laradock 中 host 必須填寫(xiě) mysql笙瑟,自動(dòng)轉(zhuǎn)發(fā)到 mysql 容器中
- 安裝
laravel/passport
composer require laravel/passport
laravel 5.5 以后有自動(dòng)發(fā)現(xiàn)機(jī)制楼镐,不需要配置 provider,低于該版本請(qǐng)按照手冊(cè)自行配置往枷。
- 執(zhí)行數(shù)據(jù)庫(kù)遷移框产,并添加 auth 腳手架。
$ php artisan migrate
$ php artisan make:auth
當(dāng)執(zhí)行完 make:auth
后首頁(yè)上就會(huì)出現(xiàn)注冊(cè)與登錄错洁。
- 生成 passport key 以及一些 password keys
php artisan passport:install
- 配置 config 文件
將 api 的driver 更換為 passport
# config/auth.config
...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
...
這一步是實(shí)現(xiàn) API Auth 授權(quán)中間件默認(rèn)使用的驅(qū)動(dòng)
- User 使用 Password 提供的 Trait
# App\User
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens;
...
}
- 配置 Passport 相關(guān)路由信息
# App\Providers\AuthServiceProvider
...
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
...
public function boot()
{
$this->registerPolicies();
// Passport 路由
Passport::routes();
// Passport Token 過(guò)期時(shí)間
Passport::tokensExpireIn(Carbon::now()->addDay(15));
// Passport Refresh Token 過(guò)期時(shí)間
Passport::refreshTokensExpireIn(Carbon::now()->addDay(30));
}
}
- 生成前端腳手架秉宿,默認(rèn)提供了 vue 相關(guān)模板,需要使用到 node
php artisan vendor:publish --tag=passport-components
- 使用 npm 或 cnpm 命令安裝 package.json 的相關(guān)依賴(lài)
composer.json 與 package.json 類(lèi)似屯碴,npm 與 composer 類(lèi)似描睦。使用 npm 必須安裝 node 環(huán)境。npm 與 composer 類(lèi)似导而,境外資源拉取非常慢忱叭,所以推薦使用淘寶鏡像。具體設(shè)置方法請(qǐng) Google今艺。
npm install
- 然后將 component 組件注冊(cè)到 vue 的根實(shí)例中
# resources/assets/js/app.js
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')
);
- 編譯文件韵丑,生成 app.js 和 app.css
npm run dev
有一些同學(xué)可能會(huì)存在相關(guān)問(wèn)題,比如筆者就遇到一個(gè)bug虚缎。
Module build failed: ReferenceError: Unknown plugin "transform-runtime"
撵彻,當(dāng)遇到這個(gè)bug時(shí)第一時(shí)間google了一下,然后各種無(wú)法解決,仔細(xì)一看千康,原來(lái)是項(xiàng)目的上一級(jí)目錄中存在一個(gè).babelrc
文件享幽,該文件 上一個(gè) vue 項(xiàng)目的殘余(沒(méi)刪除干凈),然后刪除之后就可以了拾弃。
這里筆者要說(shuō)明的是:遇到問(wèn)題不要緊張值桩,首先看一下報(bào)錯(cuò)的信息,如果是 依賴(lài)沒(méi)安裝成功就刪除 node_modules豪椿,重新安裝下奔坟。如果是存在其它 bug,首先看看是不是本項(xiàng)目的搭盾,如果不是就刪除它咳秉,如果是的話那么就 google 一下,查找一下解決方式鸯隅,或者你可以留言澜建。
- 這時(shí),你就需要可以在 blade 模板里面引入編譯好的 css 和 js 就可以了蝌以。
# resources/view/passport.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<!-- Vue 默認(rèn)綁定的根節(jié)點(diǎn) -->
<div id="app" class="container">
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
</div>
<!-- 必須放在 根節(jié)點(diǎn) 之后炕舵,否則無(wú)法正常解析-->
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
- 添加路由
# routes/web.php
Route::get('/passport', function () {
return view('passport');
});
- 訪問(wèn)路由
server.test/passport
頁(yè)面渲染,但是報(bào)錯(cuò)了 401 錯(cuò)誤跟畅,這說(shuō)明必須登錄之后才能訪問(wèn)該路由咽筋。那么進(jìn)入首頁(yè)登錄一下即可,沒(méi)有賬號(hào)就注冊(cè)一個(gè)徊件。
-
成功奸攻,并且無(wú)報(bào)錯(cuò)信息
-
創(chuàng)建一個(gè) Client
- 使用 瀏覽器 測(cè)試一下
http://server.test/oauth/authorize?client_id=your_client_id&redirect_uri=your_redirect_uri&response_type=code&scope=*
將 client_id 和 redirect_uri 替換成你自己的即可
- 響應(yīng)數(shù)據(jù)
http://client.test/authorizations?code=def50200b4bd56c76cf885df8f4871b1325aa23571c07fe149086c4a3795c7b6e286d19aef3101330fcaa7e19a8bebaabf4a3cb4cdfa6208934a4d42db4e5f2eee1ef0a78ae6da976da9764c75d7561f43cd12d3a2aacc20b94cc12b71aa2b7464c44438524e8b73c256b655168ed6087da8a82c011c1f86deb3a72cf30a4eba955579efce5cf007993c13ad1783beb43bb30980f5ac54b0a559148df3182839ee6522c0175eb24ce917f36a2b1bb70b4278dc29640d8251a83a9e8a58c559b8b7304e2edfaeb24c9f248f1eb0187ecff76ecb8ebdbd57a1da91ce4c84142946065cbdb5187e4f92f012ce49497f6fd471c2a9a6538f89a8194dda8b976f42377fa1b429237b7bf2606ab64fe459532fba35f61fb8262efc8b4931edcaaf0ff6ec87dba9894916a90ada15c9fd8f44a7520996e44bfa38fd8ae2c719cb098e673887eddbb2a01b5af9f7c062ffb991536cbdeff275a3b7a2556c595998eec98dda063759aa3d
-
通過(guò) code 獲取 access_token
把 client_id 和 client_secret 更換為你自己的
- 響應(yīng)數(shù)據(jù)解讀
token_type: Bearer 是 Oauth 2.0 的一種認(rèn)證模式,一般均為此虱痕。
expires_in: 過(guò)期時(shí)間
access_token: 通訊密鑰
refersh_token:刷新Token睹耐,是在 access_token 過(guò)期后,可以用此更換新的 access_token
還記得我們?cè)?AuthProvider中設(shè)置的過(guò)期時(shí)間么部翘?token 過(guò)期時(shí)間比 refresh_token 過(guò)期時(shí)間要短疏橄,我們?cè)O(shè)置的是 15天 和 30 天。
- 這時(shí)就可以拿著 access_token 去讀取用戶(hù)信息了
首先略就,定義一個(gè) API 路由
# routes/api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
$user = \Auth::guard('api')->user();
return response()->json($user);
});
比如,在 API 路由中去讀取用戶(hù)信息晃酒,使用 Postman 測(cè)試一下表牢。
- 恭喜,基本完成了贝次。
當(dāng)然崔兴,筆者做的實(shí)驗(yàn)是利用 client 去實(shí)現(xiàn) postman 的功能,但是發(fā)現(xiàn) postman 更好用。client 端的代碼其實(shí)就是做了一層轉(zhuǎn)發(fā)的功能敲茄,讓服務(wù)器保存 client_secret 更加安全位谋。但基于實(shí)驗(yàn),你完全可以使用 postman堰燎。
這里筆者只是基本完成了 laravel-passport 的授權(quán)模式掏父, 如果還要更深的研究,你可以留言秆剪,我可以進(jìn)行更加具體的教程解讀赊淑。
這里筆者將代碼放在 github上,如果你搭不起環(huán)境仅讽,可以直接拿來(lái)做實(shí)驗(yàn) laravel-passport-test