zoukankan      html  css  js  c++  java
  • 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']; } } }
  • 相关阅读:
    【Azure Redis 缓存】Azure Redis 功能性讨论二
    【Azure Developer】如何用Microsoft Graph API管理AAD Application里面的Permissions
    【Azure 环境】通过Python SDK收集所有订阅简略信息,例如订阅id 名称, 资源组及组内资源信息等,如何给Python应用赋予相应的权限才能获取到信息呢?
    【Azure 应用服务】App Service与APIM同时集成到同一个虚拟网络后,如何通过内网访问内部VNET的APIM呢?
    【Azure 云服务】如何从Azure Cloud Service中获取项目的部署文件
    【Azure Redis 缓存】Azure Redis 异常
    【Azure 微服务】基于已经存在的虚拟网络(VNET)及子网创建新的Service Fabric并且为所有节点配置自定义DNS服务
    【Azure Redis 缓存】遇见Azure Redis不能创建成功的问题:至少一个资源部署操作失败,因为 Microsoft.Cache 资源提供程序未注册。
    【Azure Redis 缓存】如何得知Azure Redis服务有更新行为?
    【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
  • 原文地址:https://www.cnblogs.com/yszr/p/13180320.html
Copyright © 2011-2022 走看看