first commit
This commit is contained in:
310
金壶/ydyd_service/application/api/controller/TokenController.php
Normal file
310
金壶/ydyd_service/application/api/controller/TokenController.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\model\UserModel;
|
||||
use think\Db;
|
||||
use think\facade\Cache;
|
||||
use think\Exception;
|
||||
|
||||
/**
|
||||
* 生成token
|
||||
*/
|
||||
class TokenController extends ApiController
|
||||
{
|
||||
protected $noAuth = ['login','refresh'];
|
||||
/**
|
||||
* 请求时间差
|
||||
*/
|
||||
public static $timeDif = 1000000;
|
||||
|
||||
public static $accessTokenPrefix = 'accessToken_';
|
||||
public static $refreshAccessTokenPrefix = 'refreshAccessToken_';
|
||||
public static $expires = 60*60*24*7; //暂时修改60*60*24*7
|
||||
public static $refreshExpires = 60*60*24*90; //刷新token过期时间60*60*24*90
|
||||
|
||||
/**
|
||||
* 测试appid,正式请数据库进行相关验证
|
||||
*/
|
||||
public static $appid = 'test';
|
||||
/**
|
||||
* appsercet
|
||||
*/
|
||||
public static $appsercet = '123456';
|
||||
|
||||
/*获取token*/
|
||||
public function token($user,$data)
|
||||
{
|
||||
$userInfo = [
|
||||
'id' => $user['user_id'],
|
||||
'phone' => $user['phone'],
|
||||
];
|
||||
try {
|
||||
$accessToken = self::setAccessToken(array_merge($userInfo,$data));
|
||||
return $accessToken;
|
||||
} catch (Exception $e) {
|
||||
return self::returnMsg(500,'fail',$e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @apiDefine login 活动管理
|
||||
*/
|
||||
|
||||
/**
|
||||
* @apiVersion 1.0.0
|
||||
* @api {any} / 1.整体说明(朱晓伟)
|
||||
* @apiName AAA
|
||||
* @apiGroup login
|
||||
* @apiSuccessExample Success-Response:
|
||||
* 1. 先获取token,其他接口在header里面传入authentication
|
||||
* authentication = USERID base64_encode("appid" + "-" +"uid" + "-" + "access_token" + "-" + "refresh_token") 加密后签名(参数与参数中间需要加上-号)
|
||||
* 2. 若请求地址中含有“:”,表示这个参数是在请求地址中,如:平台公告详情:/messages/platforms/:id,将:id换成不同的值,即可获得id对应的公告详情
|
||||
* 3. 状态码
|
||||
* 所有接口返回值以实际返回结果为准,接口code返回值为200,http状态码也是200表示请求成功,其他表示请求失败。
|
||||
* code值说明:
|
||||
* 401:登录相关接口验证失败时返回
|
||||
* 1xxxx:传递参数提示;
|
||||
* 2xxxx:数据验证提示;
|
||||
* 3xxxx:业务提示;
|
||||
* 4. 参数:
|
||||
* 所有请求参数,除了有“可选”的标记或列表用于搜索的参数外,其余都是必传。
|
||||
* 5. 分页参数名为page,每页展示条数由后台返回
|
||||
* {
|
||||
* "code": 200,
|
||||
* "message": "成功",
|
||||
* "data": {
|
||||
* "total": 60, // 总数据量
|
||||
* "per_page": 10, // 每页数据条数
|
||||
* "current_page": 1, // 当前页数
|
||||
* "last_page": 6, // 数据总页数
|
||||
* "data": [
|
||||
* {
|
||||
* "id": 23356,
|
||||
* ...
|
||||
* },
|
||||
* {
|
||||
* "id": 19244,
|
||||
* ...
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* }
|
||||
* 6. 各接口返回的数据中,有注释的字段都是重要或者需要可能有用的字段,未注释字段可不用理会。
|
||||
* 完善中...
|
||||
*/
|
||||
/**
|
||||
* @apiVersion 1.0.0
|
||||
* @api {post} /token/login 2.获取token 登录(朱晓伟)
|
||||
* @apiName login
|
||||
* @apiGroup login
|
||||
* @apiParam {String} phone 手机号
|
||||
* @apiParam {String} password 账号密码
|
||||
* @apiParam {String} appid
|
||||
* @apiParam {Integer} timestamp 时间戳
|
||||
* @apiParam {String} sign 签名($appsercet+$appid+account+md5(password)+时间戳)
|
||||
* @apiSuccessExample Success-Response:
|
||||
*{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"access_token": "GFkw82j36Tbs9JrCi5fA1I7ztmouxeX9",
|
||||
"expires_time": 1565762455,
|
||||
"refresh_token": "1xzjD8gJGlSZheH6wKu9pCfRt9rd4IoE",
|
||||
"refresh_expires_time": 1596693655,
|
||||
"client": {
|
||||
"id": 22, //员工ID
|
||||
"phone": "17610889520", //手机号码
|
||||
"appid": "tp5restfultest",
|
||||
"timestamp": 1565157655,
|
||||
"sign": "11420815e6b79bd3491b3664404b91fe",
|
||||
}
|
||||
}
|
||||
}
|
||||
* @apiErrorExample Error-Response:
|
||||
* {
|
||||
"code": 500,
|
||||
"message": "fail",
|
||||
"data": {
|
||||
"info": "短信验证码错误,请重新获取"
|
||||
}
|
||||
}
|
||||
*/
|
||||
public function login(){
|
||||
|
||||
try {
|
||||
$params = input('');
|
||||
self::checkParams($params); //参数校验
|
||||
|
||||
$user = Db::name("users")->where('phone',$params['phone'])->find();
|
||||
$pwd = md5($params['password'].$user['secure_password_key']);
|
||||
if($pwd != $user['password']){
|
||||
return self::returnMsg(401,'账号密码有误',[]);
|
||||
}
|
||||
$accessToken = self::token($user,$params);
|
||||
return self::returnMsg(ApiController::SUCCESS, ApiController::getMessage('SUCCESS'),$accessToken);
|
||||
} catch (Exception $e) {
|
||||
return self::returnMsg($e->getCode(), $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @apiVersion 1.0.0
|
||||
* @api {post} /token/refresh 3.刷新token (朱晓伟)
|
||||
* @apiName refresh
|
||||
* @apiGroup login
|
||||
* @apiParam {String} refresh_token 参数说明
|
||||
* @apiParam {String} appid 参数说明
|
||||
* @apiSuccessExample Success-Response:
|
||||
* {
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"access_token": "1JGKFnYE8N6C2mAvyk9lpSHZoz4WhId8",
|
||||
"expires_time": 1565852253,
|
||||
"refresh_token": "1xzjD8gJGlSZheH6wKu9pCfRt9rd4IoE",
|
||||
"refresh_expires_time": 1596783453,
|
||||
"client": {
|
||||
"appid": "tp5restfultest"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
$refresh_token = input('refresh_token');
|
||||
$cache_refresh_token = Cache::get(self::$refreshAccessTokenPrefix.$refresh_token); //查看刷新token是否存在
|
||||
if(!$cache_refresh_token){
|
||||
return self::returnMsg(ApiController::ERR_USER_REFRESH_TOKEN_EXPIRE,ApiController::getMessage('ERR_USER_REFRESH_TOKEN_EXPIRE'),[]);
|
||||
}else{
|
||||
if($cache_refresh_token['refresh_token'] !== $refresh_token){
|
||||
return self::returnMsg(ApiController::ERR_USER_TOKEN,ApiController::getMessage('ERR_USER_TOKEN'),[]);
|
||||
}else{ //重新给用户生成调用token
|
||||
$accessToken = self::setAccessToken($cache_refresh_token,$refresh_token);
|
||||
return self::returnMsg(ApiController::SUCCESS, ApiController::getMessage('SUCCESS'),$accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数检测
|
||||
*/
|
||||
public static function checkParams($params = [])
|
||||
{
|
||||
//手机号校验
|
||||
if(!$params['phone']){
|
||||
throw new Exception('手机号不能为空',401);
|
||||
}
|
||||
//密码校验
|
||||
if(!$params['password']){
|
||||
throw new Exception('密码不能为空',401);
|
||||
}
|
||||
|
||||
//时间戳校验
|
||||
if(abs($params['timestamp'] - time()) > self::$timeDif){
|
||||
throw new Exception('登录验证异常',401);//'timestamp:'.time()
|
||||
}
|
||||
|
||||
//appid检测,这里是在本地进行测试,正式的应该是查找数据库或者redis进行验证
|
||||
if($params['appid'] !== self::$appid){
|
||||
throw new Exception('登录验证异常',401);
|
||||
}
|
||||
//签名检测
|
||||
$sign = OauthController::makeSign($params,self::$appsercet);
|
||||
if($sign !== $params['sign']){
|
||||
throw new Exception('登录验证异常',401);
|
||||
}
|
||||
}
|
||||
|
||||
/**设置AccessToken
|
||||
* @param $clientInfo
|
||||
* @param null $refresh_token
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
|
||||
protected function setAccessToken($clientInfo,$refresh_token = null)
|
||||
{
|
||||
//生成令牌
|
||||
unset($clientInfo['password']);
|
||||
$accessToken = self::buildAccessToken();
|
||||
if(!$refresh_token){
|
||||
$refresh_token = self::buildAccessToken();
|
||||
}else{
|
||||
$refresh = self::getRefreshTokenInfo($refresh_token);
|
||||
$clientInfo = $refresh['client'];
|
||||
}
|
||||
$accessTokenInfo = [
|
||||
'access_token' => $accessToken,//访问令牌
|
||||
'expires_time' => time() + self::$expires, //过期时间时间戳
|
||||
'refresh_token' => $refresh_token,//刷新的token
|
||||
'refresh_expires_time' => time() + self::$refreshExpires, //过期时间时间戳
|
||||
'client' => $clientInfo,//用户信息
|
||||
];
|
||||
self::saveAccessToken($accessToken, $accessTokenInfo); //保存本次token
|
||||
self::saveRefreshToken($refresh_token,$accessTokenInfo); //保存本次refresh_token
|
||||
$res = UserModel::field('access_token,refresh_token')->where(['user_id'=>$clientInfo['id']])->find();//查询用户token refresh_token
|
||||
if($res){//如果存在 则清除之前的缓存
|
||||
Cache::rm(self::$accessTokenPrefix.$res['access_token']);
|
||||
Cache::rm(self::$refreshAccessTokenPrefix.$res['refresh_token']);
|
||||
Cache::rm('USER_INFO_API'.$clientInfo['id']);
|
||||
}
|
||||
UserModel::update(['access_token'=>$accessToken,'refresh_token'=>$refresh_token],['user_id'=>$clientInfo['id']]);//保存token和refresh_token到数据库,用于单点登录
|
||||
return $accessTokenInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新用的token检测是否还有效
|
||||
*/
|
||||
public static function getRefreshToken($appid = '')
|
||||
{
|
||||
$token = Cache::get(self::$refreshAccessTokenPrefix.$appid);
|
||||
return $token ? $token['refresh_token'] : self::buildAccessToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新用的token检测是否还有效
|
||||
*/
|
||||
public static function getRefreshTokenInfo($refresh_token)
|
||||
{
|
||||
$refresh = Cache::get(self::$refreshAccessTokenPrefix.$refresh_token);
|
||||
return $refresh ? $refresh : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成AccessToken
|
||||
* @return string
|
||||
*/
|
||||
protected static function buildAccessToken($lenght = 32)
|
||||
{
|
||||
//生成AccessToken
|
||||
$str_pol = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz";
|
||||
return substr(str_shuffle($str_pol), 0, $lenght);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储token
|
||||
* @param $accessToken
|
||||
* @param $accessTokenInfo
|
||||
*/
|
||||
protected static function saveAccessToken($accessToken, $accessTokenInfo)
|
||||
{
|
||||
//存储accessToken
|
||||
Cache::set(self::$accessTokenPrefix . $accessToken, $accessTokenInfo, self::$expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储refreshToken
|
||||
* @param $refresh_token
|
||||
* @param $accessTokenInfo
|
||||
*/
|
||||
protected static function saveRefreshToken($refresh_token,$accessTokenInfo)
|
||||
{
|
||||
//存储RefreshToken
|
||||
Cache::set(self::$refreshAccessTokenPrefix.$refresh_token, $accessTokenInfo,self::$refreshExpires);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user