1. dingo/api 安裝的問題
原因:
dingo/api
依賴的dingo/blueprint
與phpunit
都依賴了phpdocumentor/reflection-docblock
,但是以來的版本不同,導致出現了衝突。
解決方法:因為dingo/blueprint
的開發版本dev-master
解決了衝突,可以正常安裝,所以在composer.json
中新增兩句:
composer.json
.
.
.
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability" : "dev",
"prefer-stable" : true
}
新增的內容:
-
"minimum-stability" : "dev"
———設定的最低穩定性的版本是dev
也就是可以依賴開發版本的擴充套件包。 -
"prefer-stable" : true
——— Composer 優先使用更穩定的版本。
2. 回滾遷移
回滾上一次遷移
php artisan migrate:rollback
回滾所有遷移
php artisan migrate:reset
回滾所有遷移並且再執行一次
php artisan migrate:refresh
php artisan migrate:refresh --seed
3. 字串填充
str_pad —— 使用另一個字串填充字串為指定長度。
For example:
$input = "Hello World!"; // strlen($input) = 12
// pad_string 沒有指定, input 被空格字元填充,預設右側填充
echo str_pad($input, 15); // "Hello World! "
// 左側填充
echo str_pad($input, 15, '+++', STR_PAD_LEFT); // +++Hello World!
// 兩側填充,先填充右邊,再填充左邊
echo str_pad($input, 15, '+++', STR_PAD_BOTH); // +Hello World!++
echo str_pad($input, 14, '+++', STR_PAD_BOTH); // +Hello World!+
// pad_length 為負數,小於或者等於 input 的長度時,不發生填充
echo str_pad($input, 11, '+++'); // Hello World!
4. RESTful 架構 && RESTful API
RESTful 是一種軟體設計風格,由 Roy Thomas Fielding 在他的 論文中提出,全稱為Representational State Transfer
,直譯為表現層狀態轉化
。RESTful API 是目前比較成熟的一套網際網路應用程式的 API 設計理論。
資源(Resources)
資源是網路上的一種實體(一種具體資訊)。比如一段文字、一張圖片、一種服務。
URI(統一資源定位符)標識資源的所在。每種資源對應一個特定的 URI 。 URI 成了每個資源的地址或者獨一無二的標識。
所謂“上網”,就是網際網路上一系列的“資源”互動,呼叫它的 URI 。
表現層(Representation)
資源是一種實體,有多種表現形式。我們把資源的具體呈現形式,叫做他的表現層。比如,文字可以用 txt 格式表現,也可以用 HTML 格式、XML 格式、JSON 格式表現。
URL 只代表資源的實體,不是它的表現形式。
具體的表現形式,應該在 HTTP 請求的頭資訊中用 Accept 和 Content-Type 欄位指定。這兩個欄位才是對"表現層"的描述。
狀態轉化(State Transfer)
HTTP 協議是無狀態協議,所有的狀態都儲存在伺服器端。
"狀態轉化"是指客戶端透過某種手段操作伺服器,讓伺服器發生”狀態轉化“。這種轉化過程發生在表現層之上,所以就是”表現層狀態轉化“。
客戶端採取的方式,是 HTTP 協議。具體是 HTTP 協議中的四個表示操作方式的動詞:GET、POST、PUT、DELETE 。
綜述
什麼是 RESTful 架構?
(1)每一個 URI 代表一種資源。
(2)客戶端和伺服器之間,傳遞這種資源的某種表現層。
(3)客戶端透過四個 HTTP 動詞,對伺服器資源進行操作,實現”表現層狀態轉化“。
誤區
錯誤的設計
- URI 包含動詞。資源是一種實體,動作應放在 HTTP 協議中。
- URI 中加入版本號。版本號可以在 HTTP 請求投資訊的 Accept 欄位中進行區分。
參考文章:
4. 手機註冊流程
註冊流程
- 使用者輸入手機號請求圖片驗證碼
- 伺服器返回圖片驗證碼
- 使用正確的圖片驗證碼,請求簡訊驗證碼
- 伺服器呼叫簡訊運營商介面,傳送簡訊給使用者手機
- 輸入正確的簡訊驗證碼,請求註冊介面
- 完成使用者註冊
資源
- captchas:圖片驗證碼
- verificationCodes:簡訊驗證碼
- users:使用者
介面設計
- POST api/captchas:建立圖片驗證碼
- POST api/verificationsCodes:傳送簡訊驗證碼
- POST api/users:使用者註冊
5. 節流處理防止攻擊
攻擊方式:驗證碼轟炸。惡意呼叫傳送簡訊驗證碼
介面,給一個使用者手機或者多個使用者手機頻繁傳送驗證碼簡訊。
為了防止攻擊,需要採取節流機制
。節流是對介面呼叫頻率的限制,限制每個 ip 的呼叫次數
DingoApi 提供了呼叫頻率限制的中介軟體api.throttle
。
routes/api.php
$api->version('v1', [
'namepsace' => 'App\Http\Controller\Api'
], function($api) {
$api->group([
'middleware' => 'api.throttle',
// sign 登入相關配置. 次數(limit)/分鐘(expires)。expires 分鐘呼叫 limit 次
'limit' => config('api.rate_limits.sign.limit'),
'expires' => config('api.rate_limits.sign.expires'),
], function($api) {
.
.
.
});
});
6. OAuth 2.0
OAuth 是一種授權機制。第三方想要獲取系統的資料,先發出一個授權請求,資料的所有者告訴系統,同意並授權第三方應用進入系統,系統產生一個短期的進入令牌(token),用來代替密碼。第三方應用憑藉此令牌可以進入系統獲取資料。
令牌和密碼的差異
- 令牌是短期的,到期會自動失效,使用者無法自己修改。密碼一般長期有效,使用者可以修改,不修改就不發生變化。
- 令牌可以被資料所有者撤銷,會立即失效。
- 令牌有許可權範圍,對於網路來說,只讀令牌會比讀寫令牌更加安全。密碼一般是完整許可權。
OAuth 2.0 執行流程
- 使用者開啟客戶端(Client)後,客戶端請求使用者(Resource Owner)給予授權。
- 使用者同意給客戶端授權。
- 客戶端獲取上一步請求的授權,向認證伺服器(Authorization Server)請求令牌(Access Token)。
- 認證伺服器對客戶端進行認證後,確認無誤,同意發放令牌。
- 客戶端使用令牌,向資源伺服器(Resource Server)請求資源。
- 資源伺服器確認令牌無誤後,同意向客戶端開放資源。
7. 微信登入
微信公眾平臺測試賬號,登入地址 。
測試 OAuth 流程
測試工具,微信 web 開發者工具 。
微信網頁授權流程 :
- 獲取授權碼。
請求地址:https://open.weixin.qq.com/connect/oauth2/...
appid:測試賬號的appID
(公眾號的唯一標識)
redirect_uri:使用者同意授權後的回撥地址,也就是你的網站地址。
response_type:返回型別,填code
,返回回撥地址中會攜帶 code,它的值就是獲取到的授權碼。
scope:應用授權作用域,填snsapi_userinfo
state:隨機引數,可以不填。
#wechat_redirect:無論直接開啟還是做頁面302重定向時候,必須帶此引數。
替換後的請求地址:https://open.weixin.qq.com/connect/oauth2/...
說明:code 作為換取 access_token 的憑據,每次使用者授權使用的 code 都不一樣,code 只能使用一次,5 分鐘未使用會被自動過期。 - 透過 code 換取網頁授權 access_token
請求方法:https://api.weixin.qq.com/sns/oauth2/acces...
appid:測試賬號的appID
。 (公眾號的唯一標識)
serect:測試賬號的appsecret
。
code:上一步獲取的 code 引數。
grant_type: 填寫authorization_code
- 重新整理 access_token(如果需要)
請求方法:https://api.weixin.qq.com/sns/oauth2/refre...
appid:測試賬號的appID
。 (公眾號的唯一標識)
grant_type:填寫refresh_token
refresh_token:填寫透過 access_token 獲取到的 refresh_token 引數。說明:由於access_token擁有較短的有效期,當access_token超時後,可以使用refresh_token進行重新整理,refresh_token有效期為30天,當refresh_token失效之後,需要使用者重新授權。
- 拉取使用者資訊(需要 scope 為 snsapi_userinfo)
請求方法:https://api.weixin.qq.com/sns/userinfo?acc...
access_token:網頁介面呼叫憑證。此access_token與基礎支援的access_token不同。
openid:使用者的唯一標識。 (這裡指測試微信賬號的微訊號)
lang:返回國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語。
8. JSON WEB TOKEN(JWT)
JWT
可以解決 session
資料跨域共享問題。伺服器不儲存儲存 session
資料,所有的資料都儲存在客戶端,每次請求都發回給伺服器。這樣每個伺服器都能讀取到 session
資料。JWT
就是這種方案的一個代表。
JWT 原理JWT
的原理是,伺服器認證以後,生成一個 JSON
物件,發回給使用者,以後,使用者(客戶端)與伺服器通訊的時候,都要帶上這個 JSON
物件。伺服器靠這個物件認證使用者身份。為了防止 JSON
物件的資料被篡改,伺服器在生成這個物件的時候,會加上簽名。
伺服器不儲存任何 session
資料,也就是說JWT
,伺服器變成了無狀態了,從而比較容易實現擴充套件。
JWT 的資料結構JWT
實際上是一個很長的字串,中間用"點"(.
)分成三部分(Header
、Payload
、Signature
)。
- Header:頭部
- Payload:負載
- Signature:簽名
實際的表示就是: Heade.Payload.Signature
HeaderHeader
部分是一個 JSON
物件,描述 JWT
的後設資料。
{
"alg": "H256"
"typ": "JWT"
}
alg
屬性表示簽名的演算法(algorithm),預設是 HMAC SHA256 (攜程 HS256);typ
屬性表示這個令牌的型別,JWT
令牌統一攜程JWT
。
這個JSON
物件最後使用Base64URL
演算法轉成字串。
PayloadPayload
部分也是一個 JSON
物件,用來存放實際需要的傳遞的資料。JWT
規定了 7 個官方欄位,供選用。
- iss(issure):簽發人
- exp(expiration time):過期時間
- sub(subject):主題
- aud(audience):受眾
- nbf(Not Before):生效時間
- iat(Issued At):簽發時間
- jti(JWT ID):編號
除此之外,Payload
允許你自定義私有欄位。
注意:JWT
預設不加密,不要把私密資訊放在這個部分。
這個JSON
物件也要使用 Base64URL
演算法轉成字串。
SignatureSignature
部分是對前兩個欄位的簽名,防止資料篡改。
首先,伺服器需要指定一個金鑰(secret)。這個金鑰只有伺服器才知道,不能洩露給使用者。然後,使用Header
裡面指定的簽名演算法(預設是 HMAC SHA256),按照下面公式產生簽名。
HMACSHA256(
baase64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
算出簽名後,把Header
、Payload
、Signature
使用“點”(.
)連線,拼成一個字串,返回給使用者。
JWT 的使用方式
客戶端接收伺服器返回的 JWT
,可以儲存在Cookie
裡面,也可以儲存在 localStorage 。
此後,客戶端每次和伺服器進行通訊,都要帶上這個JWT
。可以放在 Cookie
裡面自動傳送,但是這樣不能跨域。更好的做法是放在 HTTP 請求的頭資訊Authorization
欄位裡面。
Authorization: Bearer <token>
另一種做法是,跨域的時候,JWT
放在 POST 請求的資料體裡面。
JWT 的特點
- JWT 預設不加密,但是可以加密。生成原始 token 後,可以使用金鑰再加密一次。
- JWT 不加密的情況下,不能將秘密資料寫入 JWT。
- JWT 不僅可以用於認證,也可以用於交換資訊。有效使用 JWT,可以降低伺服器查詢資料庫的次數。
- JWT 最大的缺點就是,伺服器不儲存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改的許可權。就是說,JWT 簽發之後,在過期之前一直有效。除非伺服器部署額外的邏輯。
- JWT 本身包含了認證資訊,一旦洩露,任何人都可以獲得該令牌的所有許可權。為了減少盜用,JWT 的有效期應該設定得比較短。對於一些比較重要的許可權,使用時應該再次對使用者進行認證。
- 為了減少盜用,JWT 不應該使用 HTTP 協議明碼傳輸,要使用 HTTPS 協議傳輸。
本作品採用《CC 協議》,轉載必須註明作者和本文連結