first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View 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返回值为200http状态码也是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);
}
}