代码功能更新
This commit is contained in:
Executable
+59
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use laytp\traits\Error;
|
||||
use think\facade\Request;
|
||||
|
||||
/**
|
||||
* Api权限服务实现者
|
||||
* Class Auth
|
||||
* @package app\api\service
|
||||
*/
|
||||
class Auth
|
||||
{
|
||||
use Error;
|
||||
protected $_noNeedLogin = [];//无需登录的方法名数组
|
||||
|
||||
/**
|
||||
* 设置无需登录的方法名数组
|
||||
* @param array $noNeedLogin
|
||||
*/
|
||||
public function setNoNeedLogin($noNeedLogin = [])
|
||||
{
|
||||
$this->_noNeedLogin = $noNeedLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取无需登录的方法名数组
|
||||
* @return array
|
||||
*/
|
||||
public function getNoNeedLogin()
|
||||
{
|
||||
return $this->_noNeedLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前节点是否需要登录
|
||||
* @param bool $noNeedLogin
|
||||
* @return bool true:需要登录,false:不需要登录
|
||||
*/
|
||||
public function needLogin($noNeedLogin = false)
|
||||
{
|
||||
$noNeedLogin === false && $noNeedLogin = $this->getNoNeedLogin();
|
||||
$noNeedLogin = is_array($noNeedLogin) ? $noNeedLogin : explode(',', $noNeedLogin);
|
||||
//为空表示所有方法都需要登录,返回true
|
||||
if (!$noNeedLogin) {
|
||||
return true;
|
||||
}
|
||||
$noNeedLogin = array_map('strtolower', $noNeedLogin);
|
||||
$request = Request::instance();
|
||||
//判断当前请求的操作名是否存在于不需要登录的方法名数组中,如果存在,表明不需要登录,返回false
|
||||
if (in_array(strtolower($request->action()), $noNeedLogin) || in_array('*', $noNeedLogin)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//默认为需要登录
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* Api权限服务门面
|
||||
* @package app\api\service
|
||||
* @method static mixed setNoNeedLogin($noNeedLogin) 设置不需要登录的方法名数组
|
||||
* @method static mixed getNoNeedLogin() 获取无需登录的方法名数组
|
||||
* @method static mixed needLogin() 获取当前节点是否需要登录
|
||||
*/
|
||||
class AuthServiceFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return Auth::class;
|
||||
}
|
||||
}
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use app\service\ConfServiceFacade;
|
||||
use laytp\traits\Error;
|
||||
use think\facade\Config;
|
||||
use think\facade\Env;
|
||||
use think\facade\Request;
|
||||
|
||||
/**
|
||||
* Api验证签名服务实现者
|
||||
* Class CheckSign
|
||||
* @package app\api\service
|
||||
*/
|
||||
class CheckSign
|
||||
{
|
||||
use Error;
|
||||
protected $_noNeedCheckSign = [];//无需验证签名的方法名数组
|
||||
|
||||
/**
|
||||
* 设置无需验证签名的方法名数组
|
||||
* @param array $noNeedCheckSign
|
||||
*/
|
||||
public function setNoNeedCheckSign($noNeedCheckSign = [])
|
||||
{
|
||||
$this->_noNeedCheckSign = $noNeedCheckSign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取无需验证签名的方法名数组
|
||||
* @return array
|
||||
*/
|
||||
public function getNoNeedCheckSign()
|
||||
{
|
||||
return $this->_noNeedCheckSign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前节点是否需要验证签名
|
||||
* @param bool $noNeedCheckSign
|
||||
* @return bool true:需要验证签名,false:不需要验证签名
|
||||
*/
|
||||
public function needCheckSign($noNeedCheckSign = false)
|
||||
{
|
||||
$noNeedCheckSign === false && $noNeedCheckSign = $this->getNoNeedCheckSign();
|
||||
$noNeedCheckSign = is_array($noNeedCheckSign) ? $noNeedCheckSign : explode(',', $noNeedCheckSign);
|
||||
//为空表示所有方法都需要验证签名,返回true
|
||||
if (!$noNeedCheckSign) {
|
||||
return true;
|
||||
}
|
||||
$noNeedCheckSign = array_map('strtolower', $noNeedCheckSign);
|
||||
$request = Request::instance();
|
||||
//判断当前请求的操作名是否存在于不需要验证签名的方法名数组中,如果存在,表明不需要验证签名,返回false
|
||||
if (in_array(strtolower($request->action()), $noNeedCheckSign) || in_array('*', $noNeedCheckSign)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//默认为需要验证签名
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证签名
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$request = Request::instance();
|
||||
$requestTime = $request->header('request-time');
|
||||
$sign = $request->header('sign');
|
||||
$signKey = ConfServiceFacade::get('system.basic.signKey');
|
||||
$backendSign = strtoupper(md5(md5($requestTime).md5($signKey)));
|
||||
if($sign != $backendSign){
|
||||
$this->setError($backendSign);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* Api验证签名服务门面
|
||||
* @package app\api\service
|
||||
* @method static mixed setNoNeedCheckSign($noNeedCheckSign) 设置不需要验证签名的方法名数组
|
||||
* @method static mixed getNoNeedCheckSign() 获取无需验证签名的方法名数组
|
||||
* @method static mixed needCheckSign() 获取当前节点是否需要验证签名
|
||||
* @method static mixed check() 验证签名
|
||||
* @method static mixed getError() 获取错误信息
|
||||
*/
|
||||
class CheckSignServiceFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return CheckSign::class;
|
||||
}
|
||||
}
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use laytp\library\Str;
|
||||
use laytp\library\Token;
|
||||
use laytp\traits\Error;
|
||||
use laytp\library\Random;
|
||||
|
||||
/**
|
||||
* Api用户服务实现者
|
||||
* @package app\api\service
|
||||
*/
|
||||
class Member
|
||||
{
|
||||
use Error;
|
||||
protected $_user = null;//实例化的用户对象
|
||||
protected $_token = null;//用户登录凭证,token
|
||||
protected $_isLogin = null;//当前用户是否登录
|
||||
protected $userModel = null;//用户数据模型
|
||||
protected $allowFields = ['id', 'email', 'nickname', 'avatar'];
|
||||
protected $tokenKeepTime = 10 * 365 * 24 * 60 * 60;//Token默认有效时长,单位秒,365天
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param $token
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function init($token)
|
||||
{
|
||||
if (!$token) {
|
||||
$this->setError('token不能为空,请重新登录');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = Token::get($token);
|
||||
if (!$data) {
|
||||
$this->setError('token无效,请重新登录');
|
||||
return false;
|
||||
}
|
||||
|
||||
$userId = intval($data['user_id']);
|
||||
if ($userId > 0) {
|
||||
$user = \app\model\Member::find($userId);
|
||||
if (!$user) {
|
||||
$this->setError('账号不存在,请重新登录');
|
||||
return false;
|
||||
}
|
||||
//用户状态 1正常 2锁定
|
||||
if ($user['status'] != 1) {
|
||||
$this->setError('账号被锁定,请联系管理员');
|
||||
return false;
|
||||
}
|
||||
$this->_user = $user;
|
||||
$this->_isLogin = true;
|
||||
$this->_token = $token;
|
||||
return true;
|
||||
} else {
|
||||
$this->setError('账号不存在,请重新登录');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱+密码注册登录
|
||||
* @param $params
|
||||
* @return bool
|
||||
*/
|
||||
public function emailRegLogin($params)
|
||||
{
|
||||
try {
|
||||
$user = \app\model\Member::where('email', '=', $params['email'])->find();
|
||||
if (!$user) {
|
||||
$data = [
|
||||
'email' => $params['email'],
|
||||
'password' => Str::createPassword($params['password']),
|
||||
'status' => 1,
|
||||
'login_time' => date('Y-m-d H:i:s'),
|
||||
'login_ip' => request()->ip(),
|
||||
];
|
||||
|
||||
$user = \app\model\Member::create($data);
|
||||
$this->_user = \app\model\Member::find($user->id);
|
||||
} else {
|
||||
$this->_user = $user;
|
||||
}
|
||||
|
||||
//设置Token
|
||||
$this->_token = Random::uuid();
|
||||
Token::set($this->_token, $user->id, $this->tokenKeepTime);
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$this->setError('操作异常');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
if (!$this->_isLogin) {
|
||||
$this->setError('你没有登录');
|
||||
return false;
|
||||
}
|
||||
//设置登录标识
|
||||
$this->_isLogin = false;
|
||||
//删除Token
|
||||
Token::delete($this->_token);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容调用user模型的属性
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->_user ? $this->_user->$name : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户信息
|
||||
*/
|
||||
public function getUserInfo()
|
||||
{
|
||||
$data = $this->_user->toArray();
|
||||
$allowFields = $this->getAllowFields();
|
||||
$userInfo = array_intersect_key($data, array_flip($allowFields));
|
||||
$userInfo = array_merge($userInfo, ['token' => $this->_token]);
|
||||
return $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取允许输出的字段
|
||||
* @return array
|
||||
*/
|
||||
public function getAllowFields()
|
||||
{
|
||||
return $this->allowFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取User模型
|
||||
* @return Member
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否登录
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLogin()
|
||||
{
|
||||
if ($this->_isLogin) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前Token
|
||||
* @return string
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->_token;
|
||||
}
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\api;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* Api用户服务门面
|
||||
* @package plugin\core\service
|
||||
* @method static mixed init($token) 初始化
|
||||
* @method static mixed getError() 获取错误信息
|
||||
* @method static mixed emailRegLogin($param) 邮箱密码注册登录
|
||||
* @method static mixed logout() 退出登录
|
||||
* @method static mixed getUserInfo() 获取登录用户信息
|
||||
* @method static mixed getUser() 获取User模型
|
||||
* @method static mixed isLogin() 获取登录状态
|
||||
* @method static mixed getToken() 获取token
|
||||
* @method static mixed getAllowFields() 允许输出的字段
|
||||
*/
|
||||
class MemberServiceFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return Member::class;
|
||||
}
|
||||
}
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
这里面写插件提供的服务
|
||||
一个服务,一般由三个文件组成
|
||||
- 服务具体实现者 这个类无需继承任何基类,只需要实现服务的具体方法
|
||||
- 服务提供者,也可以理解为服务注册者,将服务实现者类注册进ThinkPHP容器中,方便进行调用
|
||||
- 服务门面,为了在某些地方,不方便直接使用服务提供者的地方,能静态的访问服务实现者的方法,比如中间件中需要使用服务,那么就可能需要使用到服务门面
|
||||
|
||||
其中,以Service.php结尾的文件为服务提供者,服务提供者的类名全称会加入/config/service.php文件中,完成服务的注册
|
||||
|
||||
不移动到/app/common下了,负载均衡就全量复制到多个服务器
|
||||
Reference in New Issue
Block a user