本人技術(shù)不高践磅,設(shè)計(jì)有缺陷的地方還請(qǐng)各位指點(diǎn)一下单刁,或者有地方不明白可以 評(píng)論一下,我也會(huì)說出自己的思路。第一次寫文章羔飞,不知道說啥好肺樟,就直接開搞把
開發(fā)項(xiàng)目:房產(chǎn)類APP、H5
開發(fā)語言:PHP
語言框架:Yii
框架選擇:之前已經(jīng)用Thinkphp框架做了套小程序接口和后臺(tái)管理逻淌,想換個(gè)框架來重寫接口么伯,在 Yii 和 Laravel中選擇,經(jīng)過多方面的考慮和個(gè)人喜好最后選擇的Yii卡儒。
既然是混合開發(fā) 那么就需要無狀態(tài)登錄田柔,簡單介紹一下:
傳統(tǒng)的web端登錄,是將登錄信息緩存到服務(wù)端的session中骨望,每個(gè)session有唯一的sessionId硬爆,瀏覽器請(qǐng)求服務(wù)端會(huì)自動(dòng)在請(qǐng)求頭的cookie中帶上sessionId,服務(wù)端得到sessionId在session緩存器中獲取數(shù)據(jù)擎鸠。
無狀態(tài)登錄有哪些優(yōu)勢(shì)
1.服務(wù)端不需要緩存用戶信息缀磕,可以減少服務(wù)器壓力
2.token緩存在客戶端,服務(wù)器重啟劣光,登錄狀態(tài)不會(huì)失效
3.容易擴(kuò)展袜蚕,如果使用負(fù)載均衡 傳統(tǒng)登錄雖然可以實(shí)現(xiàn),但是成本和時(shí)間會(huì)大大提高绢涡,使用TOKEN就不需要麻煩牲剃,只需要多臺(tái)服務(wù)器使用相同解密代碼即可
接口安全
JWT(JSON Web Token)簽名算法 SHA512,考慮到有些隱私的數(shù)據(jù)雄可,增加了新的字段颠黎,并且使用 RSA(非對(duì)稱算法) 進(jìn)行了加密。
為什么要增加字段而不是 直接使用RSA算法對(duì)Token進(jìn)行加密:RSA加密解密速度比對(duì)稱算法要慢的多滞项,會(huì)嚴(yán)重影響接口響應(yīng)速度,浪費(fèi)服務(wù)器資源夭坪。增加字段文判,不需要每次都解密,只有需要使用的時(shí)候解密就可以了室梅。
我自己封裝好了JWT和RSA加解密戏仓,代碼有點(diǎn)多 就不好貼出來了。
接口數(shù)據(jù)安全
數(shù)據(jù)安全依然采用SHA算法簽名驗(yàn)證亡鼠,每一次請(qǐng)求 把請(qǐng)求的內(nèi)容和KEY 一起加密赏殃,并且設(shè)置接口有效期 5秒左右,服務(wù)端接收到數(shù)據(jù) 進(jìn)行 簽名和有效期驗(yàn)證间涵,由于 KEY是私密的別人無法得到就算拿到這個(gè)包也無法從服務(wù)端拿到數(shù)據(jù)仁热。
Restful 風(fēng)格設(shè)計(jì)
標(biāo)準(zhǔn)的Restful風(fēng)格,我是不太喜歡勾哩,根據(jù)這個(gè)風(fēng)格調(diào)整了下抗蠢,GET 查詢举哟,增刪改用POST,就只用了這兩種方式迅矛。
版本號(hào)方式:
apiv1.xxxx.com
接口返回結(jié)果
響應(yīng)碼:
<?php
class Code {
const success = array(
2000 => ['status' => 2000, 'msg' => '查詢成功', 'sysMsg' => 'success', 'is' => true],
2005 => ['status' => 2005, 'msg' => '查詢成功,無數(shù)據(jù)', 'sysMsg' => 'success', 'is' => true],
2001 => ['status' => 2001, 'msg' => '操作成功', 'sysMsg' => 'success', 'is' => true], // 更新或插入操作
2002 => ['status' => 2002, 'msg' => '后臺(tái)已執(zhí)行', 'sysMsg' => 'success', 'is' => true],
2004 => ['status' => 2004, 'msg' => '刪除成功', 'sysMsg' => 'success', 'is' => true]
);
const error = array(
4000 => ['status' => 4000, 'msg' => '未執(zhí)行任何操作', 'sysMsg' => 'error', 'is' => false],
4001 => ['status' => 4001, 'msg' => '驗(yàn)證碼錯(cuò)誤', 'sysMsg' => 'error', 'is' => false], // 驗(yàn)證碼用戶名或密碼錯(cuò)誤過期
4003 => ['status' => 4003, 'msg' => '無權(quán)訪問', 'sysMsg' => 'error', 'is' => false],
4004 => ['status' => 4004, 'msg' => '記錄不存在', 'sysMsg' => 'error', 'is' => false],
4006 => ['status' => 4006, 'msg' => '格式不正確', 'sysMsg' => 'error', 'is' => false],
4022 => ['status' => 4022, 'msg' => '缺少參數(shù)', 'sysMsg' => 'error', 'is' => false], // 自定義錯(cuò)誤信息
4029 => ['status' => 4006, 'msg' => '請(qǐng)求次數(shù)超過限額', 'sysMsg' => 'error', 'is' => false],
);
public static function getSCode($code)
{
return self::success[$code];
}
public static function getECode($code)
{
return self::error[$code];
}
}
復(fù)用類
Trait ResponseCode{
private static $instance;
public static function successResponse($code, $data)
{
$code = Code::getSCode($code);
$code['data'] = $data;
return json_encode($code);
}
public static function errorResponse($code, $msg = '')
{
$code = Code::getECode($code);
if ($msg != ''){
$code['msg'] = $msg;
}
return json_encode($code);
}
}
如何使用妨猩?
引入 ResponseCode 類 填入響應(yīng)狀態(tài)碼即可
return ResponseCode::successResponse(2000, $data);
Yii框架數(shù)據(jù)庫操作
在這也是 糾結(jié)了一下,活動(dòng)記錄也就是模型果斷放棄的秽褒,又在 查詢器和 createCommand做選擇 查詢器 可讀性更好些壶硅,createCommand 后期做分布式數(shù)據(jù)庫很方便。
最后還是選擇了 createCommand 销斟,它更高效庐椒,不會(huì)產(chǎn)生多余的SQL,我也進(jìn)行了簡單的封裝票堵,看起來不是那么啰嗦扼睬, 滿屏幕的 'select'的字符串,寫起來都很頭疼悴势。
代碼如下:
class Sql
{
private $db;
private static $sql;
function __construct($name = '')
{
if (!$this->db) {
$this->db = \Yii::$app->db;
}
if ($name !== '') {
$this->sql = " from {{%$name}}";
}
}
public function select(string $fields)
{
self::$sql = " select " . $fields . self::$sql;
return $this;
}
public static function from(string $name)
{
self::$sql = " from {{%$name}}";
return new self();
}
public function map($map = '')
{
if ($map) {
self::$sql .=' ' . $map;
}
return $this->db->createCommand(self::$sql);
}
}
如何使用?
use common\models\Sql;
$data = Sql::from('advert')
->select("id, title, CONCAT($dir, cateimg) as cateimg, page_url")
->map('where type = 1 and cityid = :cityid')
->bindValue(':cityid', $cityid)
->queryAll();
這樣看起來 是不是 就舒服很多了窗宇,當(dāng)然每個(gè)人想法不一樣。
我個(gè)人喜歡原生的PHP特纤,如果不是窮....
所以我的 工具類都是基于 原生PHP編寫军俊,自己寫的看起來更清晰,也能夠兼容于大部分的框架捧存。
以上就是我的設(shè)計(jì)思路粪躬,歡迎各位朋友提出寶貴的建議!大家一起進(jìn)步昔穴!