oss 上传图片鉴权,临时权限

<?php


/**
 * 公共方法
 */

defined('DYMall') or exit('Access Invalid!');

use OSSOssClient;
use OSSCoreOssUtil;
use OSSCoreOssException;
use OSSHttpRequestCore;
use OSSHttpResponseCore;


require_once(BASE_ROOT_PATH.'/library/smartphp/libraries/OSS/autoload.php');
class osssecurityCtl{

    const OSS_URL_KEY = 'ossSecurityUrl';
    const OSS_TIME = 3600;

    const OSS_STS_URL = 'https://sts.aliyuncs.com';
    const FORMAT = 'JSON';
    const VERSION = '2015-04-01';
    const SIGN_ATURE_METHOD = 'HMAC-SHA1';
    const SIGN_ATURE_VERSION = '1.0';
    const ROLE_SESSION_NAME = 'web****ss';
    const OSS_STS_TOKEN = 'images:oss:sts:token';
    const OSS_ARN = 'acs:ram::136*******:role/w*****s'; //格式说明oss官网上有说明
    const OSS_STS_ACCESS_ID = 'LTAI4****9u3h';
    const OSS_ACCESE_SECRET = 'bv*******3B';

     /**
     * The name and signature of the console command.
     * @var string
     */
    protected $signature = 'get:OssStsToken';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '[OSS]定期更新OSS Sts Token';

    public function __construct()
    {
        $this->redis = caching::getInstance();
    }

    public function index(){
        //生成token
        $token = $this->handle();

        $endpoint = $GLOBALS['setting_config']['oss_url'];
        $bucket = $GLOBALS['setting_config']['oss_pre'];
        $object = 'data/upload/mobile/share/poster/'; //oss的图片上传路径,后面必须加上反斜杠否则报错
//此处有个坑,阿里云文档中没有写明,此处因为是生成临时鉴权,来传递图片,所以用建立用户时生成的acesseckeyid去生成token,
// 生成的$token 会返回临时的 token值跟 AccessKeyId 跟 AccessKeySecret 跟Expiration 此处是生成的临时用的 acessid 跟 accesesecret
// 然后用生成的临时的 acceesskeyid 跟 accesskeysecret 跟token去生成临时鉴权的url ,不要用原来的 OSS_STS_ACCESS_ID
$ossClient = new OSSOssClient($token['AccessKeyId'], $token['AccessKeySecret'], $endpoint, false, $token['SecurityToken']); try{ $is_keys = $this->redis->exists(self::OSS_URL_KEY); if($is_keys) { $signedUrl = $this->redis->get(self::OSS_URL_KEY); }else{ // 生成PutObject的签名URL。 $signedUrl = $ossClient->signUrl($bucket, $object, self::OSS_TIME); $this->redis->set(self::OSS_URL_KEY, $signedUrl, self::OSS_TIME); } }catch (OssException $e){ output_error($e->getMessage()); } $signedUrl = $signedUrl.'&AccessKeySecret='.$token['AccessKeySecret'].'&bucketName='.$bucket.'&endpoint='.$endpoint; $arr = parse_url($signedUrl); $arrQeury = $arr['query']; $explarr = explode('&', $arrQeury); $urlarr = []; foreach($explarr as $k =>$v){ $arr1=explode('=',$v); $urlarr[$arr1[0]] = $arr1[1]; } output_data($urlarr);//此处是将数据json后返回前段,token会被转义,所以前段拿到值后需要jsondecode一下在转义回来使用 } /** * 定期更新Oss Sts token * * @return mixed */ private function handle() { if($this->redis->exists(self::OSS_STS_TOKEN)) { return $this->redis->get(self::OSS_STS_TOKEN); } date_default_timezone_set("GMT"); $params = [ // 获取公共参数 'Format' => self::FORMAT, 'Version' => self::VERSION, 'AccessKeyId' => self::OSS_STS_ACCESS_ID, 'SignatureMethod' => self::SIGN_ATURE_METHOD, 'SignatureVersion' => self::SIGN_ATURE_VERSION, 'SignatureNonce' => uniqid(), 'Timestamp' => date('Y-m-dTH:i:s'), // 获取接口参数 'Action' => 'AssumeRole', 'RoleArn' => self::OSS_ARN, 'RoleSessionName' => self::ROLE_SESSION_NAME, ]; ksort($params); $oss_access_key = self::OSS_ACCESE_SECRET; $sign = ''; $items = []; foreach($params as $key => $value){ $items[] = rawurlencode($key) . '=' . rawurlencode($value); $sign .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value); } $sign = 'GET&%2F&' . $this->percentencode(substr($sign, 1)); $signature = base64_encode(hash_hmac('sha1', $sign, $oss_access_key . "&", true)); $url = self::OSS_STS_URL . '?' . implode('&', $items) . '&Signature=' . rawurlencode($signature); $token = $this->getApi($url); $time = date('Y-m-d H:i:s', time()); if (!empty($token)) { $this->redis->set(self::OSS_STS_TOKEN, $token, self::OSS_TIME); return $token; } } private function percentEncode($str) { $res = urlencode($str); $res = preg_replace('/+/', '%20', $res); $res = preg_replace('/*/', '%2A', $res); $res = preg_replace('/%7E/', '~', $res); return $res; } private function getApi($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); $output = json_decode($output,true); if(!isset($output['Credentials'])){ return false; }else{ return $output['Credentials']; } } }
原文地址:https://www.cnblogs.com/yszr/p/13180320.html