<?php
/**
 * 处理token生成与校验
 */
namespace app\api\service;

use app\api\exception\AppIdOrAppSecretInvalid;
use app\api\exception\InvalidTokenException;
use app\api\validate\TokenValidate;
use app\api\exception\SignIsNotInvalid;
use think\Db;
use think\facade\Cache;
use think\facade\Request;

class Token
{
    /**
     * 生成token之前  先验证签名
     * @return string
     */
    public function create(){
        $appId = request()->get('app_id');
        $sign = request()->get('sign');
        $timestamp = request()->get('timestamp');
        (new TokenValidate)->scene('create')->verify();

         $condition['app_id'] = $appId;
        $result = Db::table('key')->where($condition)->find();
        if(!$result){
            throw new AppIdOrAppSecretInvalid;
        }
        //服务端生成签名sign与客户端sign进行比较
        $serveSign = md5(sha1($result['app_secret'].$timestamp.$result['serverAuthenticateStaticKey']));
        if($sign !== $serveSign){
         //签名错误，无法生成token
           throw new SignIsNotInvalid; 
        }
        return $this->createToken($appId,$result['app_secret'],$result['serverAuthenticateStaticKey'],$timestamp);
    }

    private function createToken($appId,$app_secret,$serverAuthenticateStaticKey,$timestamp){
        $token = md5(sha1($app_secret.$serverAuthenticateStaticKey.$timestamp));
        Cache::store('redis')->set($token,$appId,7200);
        $data['token']=$token;
        $data['expire_in']=7200;
        return json(['code'=>200,'message'=>'SUCCESS','data'=>$data]);
    }

    /**
     * 校验token是否有效
     * @return bool
     */
    public function check(){
        (new TokenValidate)->scene('check')->verify();
        $token = Request::get('token');
        if( Cache::store('redis')->get($token)){
            return true;
        } else {
            throw new InvalidTokenException;
        }
    }
}