| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 | 
							- <?php
 
- /**
 
-  * Created by PhpStorm.
 
-  * User: 中闽 < 1464674022@qq.com >
 
-  * Date: 2019/12/5
 
-  * Time: 17:44
 
-  */
 
- namespace app\api\controller\base;
 
- use app\common\model\User;
 
- use Exception;
 
- use Firebase\JWT\JWT;
 
- use Firebase\JWT\Key;
 
- use think\exception\HttpResponseException;
 
- /**
 
-  * 登入鉴权的接口父类
 
-  * Class Permissions
 
-  * @package app\api\controller\base
 
-  */
 
- class Permissions extends Base
 
- {
 
-     const JWT_COOKIE_NAME = 'x-token';
 
-     const JWT_SESSION_NAME = 'user_info';
 
-     private $userId;
 
-     private $user;
 
-     protected function _initialize()
 
-     {
 
-         parent::_initialize();
 
-         //get token from header param body
 
-         $jwt = $this->request->header('x-token', "");
 
-         if (!$jwt) {
 
-             $jwt = $this->request->param('x-token', "");
 
-             if (!$jwt) {
 
-                 $callbackBody = file_get_contents('php://input');
 
-                 if (!$callbackBody) {
 
-                     $this->json_error('请先登入', null, self::ERR_CODE_LOGIN);
 
-                 }
 
-                 $callbackJson = json_decode($callbackBody, true);
 
-                 $jwt = isset($callbackJson['x-token']) ? $callbackJson['x-token'] : '';
 
-                 if (!$jwt) {
 
-                     $this->json_error('请先登入', null, self::ERR_CODE_LOGIN);
 
-                 }
 
-             }
 
-         }
 
-         //check x-token
 
-         try {
 
-             JWT::$leeway = 60;
 
-             $jwt_key = system_salt();
 
-             $decoded = JWT::decode($jwt, new Key($jwt_key, 'HS256'));
 
-             $arr = (array)$decoded;
 
-             if (!isset($arr['exp']) || $arr['exp'] < time()) {
 
-                 self::clear_session();
 
-                 throw new \think\Exception('登入超时,请重新登录');
 
-             } else {
 
-                 //鉴权成功
 
-                 $this->userId = $arr['data']->userId;
 
-                 $loginTime = $arr['data']->loginTime;
 
-                 $exptime = $arr['exp'];
 
-                 //限制账号多次登入
 
- //                if ($this->getUser()->getData('login_time') > $loginTime) {
 
- //                    $this->clear_session();
 
- //                    throw new \think\Exception('您的账号已经在其它地方登入');
 
- //                }
 
-                 // 每次刷新jwt,loginTime要保持不变
 
-                 self::createJwt($this->userId, $loginTime, 3600, $exptime);
 
-                 return;
 
-             }
 
-         } catch (Exception $e) {
 
-             if ($e instanceof HttpResponseException) {
 
-                 $this->json_error($e->getResponse()->getData()['msg']);
 
-             }
 
-             switch ($e->getMessage()) {
 
-                 case "Expired token":
 
-                     self::clear_session();
 
-                     $this->json_error('登入超时,请重新登录', null, self::ERR_CODE_LOGIN);
 
-                     break;
 
-                 case "Wrong number of segments":
 
-                     self::clear_session();
 
-                     $this->json_error('Token验证失败,请重新登录', null, self::ERR_CODE_LOGIN);
 
-                     break;
 
-                 default:
 
-                     $msg = "error:" . $e->getMessage();
 
-                     $this->json_error($msg);
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * 获取登入token,并设置登入状态
 
-      * @param $userId int 用户id
 
-      * @param $loginTime int 用户登入时间
 
-      * @param int $expire 设置jwt过期时间,从当前时间开始计算
 
-      * @param null $exp 强制指定过期时间,用来刷新jwt
 
-      * @return string
 
-      */
 
-     public static function createJwt($userId, $loginTime, $expire = 3600, $exp = null)
 
-     {
 
-         $nowtime = time();
 
-         $exptime = $exp ? $exp : $nowtime + $expire;
 
-         //添加 exptime,后端可以判断过期并退出, 不通过session
 
-         $data = ['userId' => $userId, 'loginTime' => $loginTime, 'exptime' => $exptime];
 
-         $token = [
 
-             'iss' => PRODUCT_URL, //签发者
 
-             'aud' => PRODUCT_URL, //jwt所面向的用户
 
-             'iat' => $nowtime, //签发时间
 
-             'nbf' => $nowtime + 10, //在什么时间之后该jwt才可用
 
-             'exp' => $exptime, //过期时间
 
-             'data' => $data //不要存放隐私信息,jwt可以保证内容不被修改,但可以被解码查看内容
 
-         ];
 
-         // 得到jwt
 
-         $jwt_key = system_salt();
 
-         $jwt = JWT::encode($token, $jwt_key, 'HS256');
 
-         //设置登入状态
 
-         session(self::JWT_SESSION_NAME, $data);
 
-         cookie(self::JWT_COOKIE_NAME, $jwt, 3600 * 12);
 
-         return $jwt;
 
-     }
 
-     /**
 
-      * 获取user对象
 
-      * @return null|User
 
-      */
 
-     protected function getUser()
 
-     {
 
-         if (!$this->user) {
 
-             $user = User::get($this->userId);
 
-             if (!$user) {
 
-                 $this->json_error('找不到用户信息,请重新登入', null, self::ERR_CODE_LOGIN);
 
-             }
 
-             $this->user = $user;
 
-         }
 
-         return $this->user;
 
-     }
 
-     /**
 
-      * 获取userid
 
-      * @return null
 
-      */
 
-     protected function getUserId()
 
-     {
 
-         return $this->userId;
 
-     }
 
-     /**
 
-      * 退出登入状态
 
-      */
 
-     public static function clear_session()
 
-     {
 
-         cookie(self::JWT_COOKIE_NAME, null);
 
-         session(self::JWT_SESSION_NAME, null);
 
-     }
 
- }
 
 
  |