app接口設(shè)計(jì)之token的php實(shí)現(xiàn)
1梅忌、首先說(shuō)一句什么是接口:接口簡(jiǎn)單來(lái)說(shuō)就是服務(wù)器端用來(lái)返回給其他程序或者客戶(hù)端數(shù)據(jù)的橋梁
2捻脖、接口的作用:根據(jù)固定參數(shù)返回固定數(shù)據(jù)干发,比如客戶(hù)端傳a=1撬统,那么服務(wù)器端返回a的姓名甥材,客戶(hù)端傳a=2怠晴,服務(wù)器端返回a的性別赴捞,而不會(huì)返回其他數(shù)據(jù)笨忌。
3频丘、signature簽名的作用:保證接口與數(shù)據(jù)的安全
4办成、token的作用:和PC登陸的session一樣,作為用戶(hù)進(jìn)入的唯一票據(jù)
例如:app與服務(wù)器端的接口搂漠、java與php之間不同程序的接口迂卢,這些接口一般通過(guò)json格式傳輸數(shù)據(jù)
所以為了保證移動(dòng)端和服務(wù)端數(shù)據(jù)傳輸相對(duì)安全,需要對(duì)接口進(jìn)行加密傳輸
1、token的設(shè)計(jì)目的:
因?yàn)锳PP端沒(méi)有和PC端一樣的session機(jī)制而克,所以無(wú)法判斷用戶(hù)是否登陸靶壮,以及無(wú)法保持用戶(hù)狀態(tài),所以就需要一種機(jī)制來(lái)實(shí)現(xiàn)session员萍,這就是token的作用亮钦,token是用戶(hù)登陸的唯一票據(jù),只要APP傳來(lái)的token和服務(wù)器端一致充活,就能證明你已經(jīng)登陸(就和你去看電影一樣蜂莉,需要買(mǎi)票,拿著票就能進(jìn)了)
2混卵、token設(shè)計(jì)時(shí)的種類(lèi):
(1)第三方登陸型:這種token形如微信的access_token映穗,設(shè)計(jì)原理是按照OAuth2.0來(lái)的,其特點(diǎn)是定時(shí)刷新(比如兩小時(shí)刷新)幕随,目的是因?yàn)閿?shù)據(jù)源將登陸權(quán)限賦予第三方服務(wù)器時(shí)必須要控制其有效期和權(quán)限蚁滋,要不然第三方服務(wù)器可以不經(jīng)過(guò)用戶(hù)同意,無(wú)限期從數(shù)據(jù)源服務(wù)器獲取用戶(hù)任意數(shù)據(jù)
(2)APP自用登陸型:這種token就是一般的APP用的token赘淮,因?yàn)椴唤?jīng)過(guò)第三方辕录,而是用戶(hù)直接取數(shù)據(jù)源服務(wù)器數(shù)據(jù),所以設(shè)計(jì)比較隨意梢卸,只需要保證其token的唯一性就行
3走诞、APP自用登陸型token實(shí)現(xiàn)步驟:
(1)數(shù)據(jù)庫(kù)用戶(hù)表添加token字段和time_out這個(gè)token過(guò)期時(shí)間字段
(2)用戶(hù)登陸時(shí)(注冊(cè)時(shí)自動(dòng)登陸也需要)生成一個(gè)token和過(guò)期時(shí)間存入表中
(3)在其他接口調(diào)用前,判斷token是否正確蛤高,正確則繼續(xù)蚣旱,錯(cuò)誤則讓用戶(hù)重新登陸
4、APP自用登陸型token實(shí)現(xiàn)代碼(公司自用框架及邏輯戴陡,主要看邏輯塞绿,不要直接復(fù)制代碼):
(1)//下面是用戶(hù)登陸時(shí)把token插入數(shù)據(jù)庫(kù)的代碼
$logininfo['token'] = appuser::settoken();
$time_out = strtotime("+7 days");
db::setByPk('u_adver', array('token1' => $logininfo['token'], 'time_out' => $time_out), $logininfo['id']);
(2)//下面是生成token方法代碼
public static function settoken()
{
$str = md5(uniqid(md5(microtime(true)),true)); //生成一個(gè)不會(huì)重復(fù)的字符串
$str = sha1($str); //加密
return $str;
}
(3)//下面是每個(gè)接口都必須調(diào)用的token驗(yàn)證代碼,驗(yàn)證具體實(shí)現(xiàn)是在(4)
$args['token'] = $_POST['token'];
$tokencheck = appuser::checktokens($args['token'], 'u_adver');
if ($tokencheck != 90001)
{
$res['msg_code'] = $tokencheck;
v_json($res);
}
(4)//token驗(yàn)證方法恤批,db::是數(shù)據(jù)庫(kù)操作類(lèi)异吻,這里設(shè)置是token如果七天沒(méi)被調(diào)用則需要重新登陸(也就是說(shuō)用戶(hù)7天沒(méi)有操作APP則需要重新登陸),如果某個(gè)接口被調(diào)用喜庞,則會(huì)重新刷新過(guò)期時(shí)間
public static function checktokens($token, $table)
{
$res = db::getOneForFields($table, 'time_out', 'token1 = ?', array($token));
if (!empty($res))
{
if (time() - $res['time_out'] > 604800) //604800是七天
{
return 90003; //token長(zhǎng)時(shí)間未使用而過(guò)期诀浪,需重新登陸
}
$new_time_out = time() + 604800;
if (db::setWhere($table, array('time_out' => $new_time_out), 'token1 = ?', array($token)))
{
return 90001; //token驗(yàn)證成功,time_out刷新成功赋荆,可以獲取接口信息
}
}
return 90002; //token錯(cuò)誤驗(yàn)證失敗
}