一、概述

阿里云OSS的授权访问主要分为两大步骤

  1. 服务端传入endpoint、accessKeyId和accessKeySecret等参数利用SDK获取链接。
  2. 客户端向服务端请求链接,然后自行处理(当然也可以使用SDK来直接下载文件)

那么现在有几个问题。

a)endpoint、accessKeyId和accessKeySecret分别在哪里获取?

字段

获取

示例

endpoint

访问域名

http://oss-cn-shenzhen.aliyuncs.com

accessKeyId

进入OSS控制台-右上角头像-accesskeys-开始使用子用户AccessKey(在这里可以创建用户,创建用户之后进入对应的用户详情,最底下可以创建Accesskey,创建之后可以获取)

LTAIbGu3gN78XXX

accessKeySecret

这是在创建Accesskey的时候出现的,需要及时保存下来,一旦你关闭弹窗,就无法找回了

c0wtySPhGJSioIbI1vYXXXXXX

bucketName

OSS控制台创建

tjbaobao

objectName

文件名称(需要携带文件夹名称)

folderName/fileName

b) 服务端SDK怎么下载(官方文档)

平台

连接

JAVA

直接下载

PHP

通过GitHub下载

Python

通过GitHub下载

二、实现

JAVA服务端实现

import com.aliyun.oss.OSSClient;

import java.net.URL;
import java.util.Date;

public class AliyunOSSUtil {

    // Endpoint以深圳为例,其它Region请按实际情况填写。
    private static final String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
    private static final String accessKeyId = "LTAIbGu3gxxxx";
    private static final String accessKeySecret = "c0wtySPhGJSioIbI1vYsxxxx";

    private final static OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

    public static String getUrl(String bucketName,String objectName)
    {
        // 设置URL过期时间为24小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000 * 24);
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        return url.toString();
    }
}

import com.aliyun.oss.OSSClient;

import java.net.URL;
import java.util.Date;

public class AliyunOSSUtil {

    // Endpoint以深圳为例,其它Region请按实际情况填写。
    private static final String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
    private static final String accessKeyId = "LTAIbGu3gxxxx";
    private static final String accessKeySecret = "c0wtySPhGJSioIbI1vYsxxxx";

    private final static OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

    public static String getUrl(String bucketName,String objectName)
    {
        // 设置URL过期时间为24小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000 * 24);
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        return url.toString();
    }
}

Android客户端实现(添加了预加载和缓存的功能)

注意:我这里使用了我框架的方法(TJFramework),有的方法你们没有的可以根据大概意思自己写。

/**
 * 作者:TJbaobao
 * 时间:2018/9/29  10:19
 * 说明:
 * 使用:
 */
public class AliyunOOSUtil {

    private static final String BucketName = "tjbaobao";
    private static final String ObjectNameHome = "TJFramework";
    private static final String ServerIP = "xxxx.com:8080";
    private static final String ServerUrl = "http://" + ServerIP + "/TJFramework/AliyunOSSServlet";

    private static final Map<String, String> mapUrl = new HashMap<>();
    private static final String AliyunUrlKey = "Aliyun_Url_Key";
    //这里应该由服务端查询数据库获取,我只是依据自己的需求写死了而已
    private static final String[] objectNames = new String[]{"lakes-02_m_2.jpg","lakes-04_m_2.jpg","lakes-07_2.jpg"};
	//在启动App的时候调用
    public static void init() {
        initCache();
        update();
    }
	//通过文件名获取链接
    @Nullable
    public static String getUrl(@NonNull String name)
    {
        if(mapUrl.containsKey(name))
        {
            return mapUrl.get(name);
        }
        else
        {
            update();
        }
        return null;
    }
	//通过本地缓存来初始化链接缓存表
    private static void initCache() {
        String urlValues = (String) Tools.getSharedPreferencesValue(AliyunUrlKey, null);
        if (urlValues != null) {
            try {
                JSONArray jsonArray = new JSONArray(urlValues);
                int arraySize = jsonArray.length();
                for (int i = 0; i < arraySize; i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject != null) {
                        String key = jsonObject.getString("key");
                        String url = jsonObject.getString("url");
                        if (key != null && url != null) {
                            mapUrl.put(key, url);
                        }
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
	//通过联网向服务端请求并更新链接缓存表
    private static void update()
    {
        RxJavaUtil.runOnIOThread(() -> {
            for(String name:objectNames)
            {
                String httpUrl = ServerUrl+"?bucketName="+BucketName+"&objectName="+ObjectNameHome+"/"+name;
                String imageUrl = OKHttpUtil.doGet(httpUrl);
                if(imageUrl!=null)
                {
                    if(mapUrl.containsKey(name))
                    {
                        String urlCache = mapUrl.get(name);
                        if(!imageUrl.equals(urlCache))
                        {
                            mapUrl.put(name,imageUrl);
                            //删除过期的链接对应的文件
                            String cacheFilePath = FileDownloader.getFilePath(urlCache);
                            FileUtil.delFileIfExists(cacheFilePath);
                        }
                    }
                    else
                    {
                        mapUrl.put(name,imageUrl);
                    }
                }
            }
            JSONArray jsonArray = new JSONArray();
            for(String key:mapUrl.keySet())
            {
                String url = mapUrl.get(key);
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("key",key);
                    jsonObject.put("url",url);
                    jsonArray.put(jsonObject);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Tools.setSharedPreferencesValue(AliyunUrlKey,jsonArray.toString());
        });
    }

}


 /**
 * 作者:TJbaobao
 * 时间:2018/9/29  10:19
 * 说明:
 * 使用:
 */
public class AliyunOOSUtil {

    private static final String BucketName = "tjbaobao";
    private static final String ObjectNameHome = "TJFramework";
    private static final String ServerIP = "xxxx.com:8080";
    private static final String ServerUrl = "http://" + ServerIP + "/TJFramework/AliyunOSSServlet";

    private static final Map<String, String> mapUrl = new HashMap<>();
    private static final String AliyunUrlKey = "Aliyun_Url_Key";
    //这里应该由服务端查询数据库获取,我只是依据自己的需求写死了而已
    private static final String[] objectNames = new String[]{"lakes-02_m_2.jpg","lakes-04_m_2.jpg","lakes-07_2.jpg"};
	//在启动App的时候调用
    public static void init() {
        initCache();
        update();
    }
	//通过文件名获取链接
    @Nullable
    public static String getUrl(@NonNull String name)
    {
        if(mapUrl.containsKey(name))
        {
            return mapUrl.get(name);
        }
        else
        {
            update();
        }
        return null;
    }
	//通过本地缓存来初始化链接缓存表
    private static void initCache() {
        String urlValues = (String) Tools.getSharedPreferencesValue(AliyunUrlKey, null);
        if (urlValues != null) {
            try {
                JSONArray jsonArray = new JSONArray(urlValues);
                int arraySize = jsonArray.length();
                for (int i = 0; i < arraySize; i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject != null) {
                        String key = jsonObject.getString("key");
                        String url = jsonObject.getString("url");
                        if (key != null && url != null) {
                            mapUrl.put(key, url);
                        }
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
	//通过联网向服务端请求并更新链接缓存表
    private static void update()
    {
        RxJavaUtil.runOnIOThread(() -> {
            for(String name:objectNames)
            {
                String httpUrl = ServerUrl+"?bucketName="+BucketName+"&objectName="+ObjectNameHome+"/"+name;
                String imageUrl = OKHttpUtil.doGet(httpUrl);
                if(imageUrl!=null)
                {
                    if(mapUrl.containsKey(name))
                    {
                        String urlCache = mapUrl.get(name);
                        if(!imageUrl.equals(urlCache))
                        {
                            mapUrl.put(name,imageUrl);
                            //删除过期的链接对应的文件
                            String cacheFilePath = FileDownloader.getFilePath(urlCache);
                            FileUtil.delFileIfExists(cacheFilePath);
                        }
                    }
                    else
                    {
                        mapUrl.put(name,imageUrl);
                    }
                }
            }
            JSONArray jsonArray = new JSONArray();
            for(String key:mapUrl.keySet())
            {
                String url = mapUrl.get(key);
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("key",key);
                    jsonObject.put("url",url);
                    jsonArray.put(jsonObject);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Tools.setSharedPreferencesValue(AliyunUrlKey,jsonArray.toString());
        });
    }

}

三、自定义权限配置

  1. 点击右上角头像-选择访问控制。
  2. 选择策略管理-自定义策略

    3.新建授权策略-选择一个和你想要的相接近的模板-编辑

a) oss仅读-指定文件夹-模板

{
  "Statement": [
    {
      "Action": [
        "oss:Get*",
        "oss:List*"
      ],
      "Effect": "Allow",
      "Resource": "acs:oss:*:*:tjbaobao/TJFramework/*"
    }
  ],
  "Version": "1"
}
//tjbaobao是bucket名,TJFramework是文件夹