• tp5 对接学科网api



      protected $appKey = '';
      protected $appSecret = '';
      protected $service = '';  //所使用的服务地址
      protected $oauthServerUrl = ''; //授权地址
      protected $notifyUrl = 'http://cs.*****.com/index/index/notify';  //回调地址


      
      //先获取code,然后再用code换取openid 

    public function index()
    {
    import('aes.Aes',EXTEND_PATH); //引入AES类(文档后面会附上)
    $aes = new Aes($this->appSecret);
    $time = time()."000"; //学科网要求必须是毫秒单位,所以直接给他拼接了三个0(简单粗暴)
    $encrypted = $aes->encrypt($time); //使用ECB-128-pkcs5 进行加密 后面会附上AES类,可使用:http://tool.chacuo.net/cryptaes 此网站验证加密的是否正确,加密后能解出来就是对的,输出为base64-utf8
    //md5参数:这里其实还有一个参数:openid,是选填的,如果已经有这个openid,直接带上会跳转,不用再进行授权
    $params = array(
    "client_id" =>$this->appKey,
    "timespan" =>$encrypted,
    "redirect_uri" =>$this->notifyUrl,
    "service" =>$this->oauthServerUrl,
    );

    $params["signature"] = $this->createSign($params,$this->appSecret);//md5规则:进行ascii进行参数key升序培训,排完再进行参数的value拼接,最后拼上appSecret,进行md5,取32位小写。后附上方法
            $data = http_build_query($params); 
    $url = $this->oauthServerUrl."/oauth2/authorize?";
    $url .= "&" . $data;
    $this->redirect($url, 302);// tp5的重定向方法
    }


      
      
    至此,会跳转到学科网的登录页面,进行登录授权。,用户登录完,会返回code至 notifyUrl 上,如果未跳转,也会有相应的错误提示
     


      获取成功示例:

      {"access_token":"VEdULTI2Ny1WdXRv*************************MS56eHhrLmNvbSM4MDg=","expires":7200}


      不太懂失败是什么样的...........

      
      public function notify()
    {
    $param = $this->request->param();
    if(empty($param)){
    return false;
    }

    $uid = 1;
    $params = array(
    "client_id" =>$this->appKey,
    "redirect_uri" =>$this->notifyUrl,
    "code" =>$param["code"],
    );
    $params["signature"] = $this->createSign($params,$this->appSecret);

    $url = $this->oauthServerUrl."/oauth2/accessToken?";
    $data = http_build_query($params);
    $url .= "&" . $data;
    $rs = $this->getHtml($url,$data); //进行curl获取openid
    $rs = json_decode($rs,true);
    if(isset($rs["error"])){
    //这里最好写个错误日志
    return false;
    }
            $url = $this->oauthServerUrl . "/oauth2/profile?access_token={$rs["access_token"]}";
    $rs = $this->getHtml($url, $data);
    $rs = json_decode($rs, true);
    if (isset($rs["error"])) {
    return false;
    }
            //获取到openid后,最好绑定到uid上,那边技术说不会随便变更,下次如果有,可直接进行跳转服务连接,不用再授权
    Db::name("user")->where("id",$uid)->setField("openid",$rs["open_id"]);

    $url = $this->oauthServerUrl . "?service={$this->service}";
    $this->redirect($url, 302);// 跳转到指定的学科网服务上
        }


    下面附上签名方法和curl方法

    
    
    /**
    * 签名生成算法
    * @access public
    * @param array data 加密参数
    * @param string key 用户秘钥
    * @return string sign 签名
    */
    protected function createSign($data, $key)
    {
    if (!$data || !$key) {
    return false;
    }
    $sort_key = array_keys($data);
    //排序
    sort($sort_key);
    $str = "";
    //拼接
    foreach ($sort_key as $v) {
    $str .= $data[$v];
    }
    //拼接key
    $str .= $key;
    //MD5加密
    $str = md5($str);
    return $str;
    }

      
      //curl

    protected function getHtml($url, $data = '')
    {
    $curl = curl_init();
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
    $data = curl_exec($curl);
    // ob_end_clean();
    curl_close($curl);
    return $data;
    }



      
    下面附上AES类



      tp5 文件路径:
     
     
    <?php


    class Aes
    {
    /**
    * var string $method 加解密方法,可通过openssl_get_cipher_methods()获得
    */
    protected $method;

    /**
    * var string $secret_key 加解密的密钥
    */
    protected $secret_key;

    /**
    * var string $iv 加解密的向量,有些方法需要设置比如CBC
    */
    protected $iv;

    /**
    * var string $options (不知道怎么解释,目前设置为0没什么问题)
    */
    protected $options;

    /**
    * 构造函数
    *
    * @param string $key 密钥
    * @param string $method 加密方式
    * @param string $iv iv向量
    * @param mixed $options 还不是很清楚
    *
    */
    public function __construct($key, $method = 'AES-128-ECB', $iv = '', $options = 0)
    {
    // key是必须要设置的
    $this->secret_key = isset($key) ? $key : 'morefun';

    $this->method = $method;

    $this->iv = $iv;

    $this->options = $options;
    }

    /**
    * 加密方法,对数据进行加密,返回加密后的数据
    *
    * @param string $encryptStr 要加密的数据
    *
    * @return string
    *
    */
    public function encrypt($encryptStr) {
    $localIV = $this->iv;
    $encryptKey = $this->secret_key;

    //Open module
    $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, $localIV);

    mcrypt_generic_init($module, $encryptKey, $localIV);

    //Padding
    $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $pad = $block - (strlen($encryptStr) % $block); //Compute how many characters need to pad
    $encryptStr .= str_repeat(chr($pad), $pad); // After pad, the str length must be equal to block or its integer multiples

    //encrypt
    $encrypted = mcrypt_generic($module, $encryptStr);

    //Close
    mcrypt_generic_deinit($module);
    mcrypt_module_close($module);

    return base64_encode($encrypted);

    }

    /**
    * 解密方法,对数据进行解密,返回解密后的数据
    *
    * @param string $encryptStr 要解密的数据
    *
    * @return string
    *
    */
    public function decrypt($encryptStr) {
    $decrypted= mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$this->secret_key,base64_decode($encryptStr), MCRYPT_MODE_ECB);
    $dec_s = strlen($decrypted);
    $padding = ord($decrypted[$dec_s-1]);
    $decrypted = substr($decrypted, 0, -$padding);

    return $decrypted;
    }
    }


  • 相关阅读:
    oracle 存储过程的基本语法
    Silverlight :服务器返回错误: NotFound 错误
    利用CSS定位背景图片 backgroundposition
    解决 asp.net 伪静态 IIS设置后 直正HTML无法显示的问题
    输入框下拉列表提示
    同步文本框内容的JS代码
    判断文本框只能输入中文汉字的代码
    如何解决padding标记在ie7、ie6以及firefox中的兼容问题
    ASP.NET用URLRewriter.dll实现伪静态
    滑动效果,适合做faq或menu
  • 原文地址:https://www.cnblogs.com/j-jian/p/12667446.html
Copyright © 2020-2023  润新知