[Azure] 透過程式的撰寫,呼叫Azure REST API以清除CDN的快取檔案

Azure的CDN服務,可以提供各區域端點進行快速的檔案複寫,並達到快速讀取檔案與資料的功能
但是CDN的服務有一個缺點,同時也是優點,那就是檔案的快取機制
若是原本的檔案進行了變更,就必須至Azure Portal上進行CDN端點快取清除的動作,當然Azure也有提供API可以進行操作

這篇文章將會說明,如何透過程式碼的方式,呼叫Azure CDN的API,進行檔案快取的清除

由於透過程式碼清除CDN檔案快取的動作,是採用呼叫Azure REST API的方式,所以必須在Header中加入AccessToken的值進行認證(類似Azure AD Graph API的模式)
所以,請照著下面的步驟建立自己呼叫API的程式

1.在CDN服務的同一個訂閱帳號中,點選[Azure Active Directory]的功能項目

2.在[Azure Active Directory]的功能中,點選[應用程式註冊],並點選[+新增應用程式註冊]的功能

3.在新增應用程式註冊的畫面中,給予這個應用程式一個名稱,並於[應用程式類型]選擇[Web 應用程式/API],如果你是透過WindowsApp或是Xamarin等等其他的程式,就將類型選到[原生]即可。而登入URL可以先填入一個暫時的URL字串,可以後續再回來作更改

4.點選剛剛建立好的註冊應用程式,再點選[設定]=>[必要權限]=>[+加入],在這個步驟必須加入可以讓這個應用程式可以呼叫API的權限

5.加入API存取權的項目裡,請選擇加入[Windows Azure Service Management API]

6.接著在選取權限的項目中,勾選[Access Azure Service Management as organization users]的項目並儲存

7.接著,在這個新註冊的應用程式中,請記下兩個資訊,一個是應用程式識別碼另一個是在[設定]=>[金鑰],建立一個應用程式金鑰

金鑰要等到儲存的時候才會顯示,而且關閉視窗後就會消失,所以請在儲存後馬上記起來

8.再來回到CDN的功能,並點選要透過API清除快取資料的端點項目

9.在端點的項目中,點選[存取控制 (IAM)]=>[+新增]

10.在新增的畫面中,選擇剛剛加入註冊的應用程式,並給予[CDN 端點參與者]的權限

到這裡,Azure上的設定就已經完成了,接下來我們就可以開始進行程式碼的編寫

1.首先,開啟Visual Studio,並建立一個WebAPI的專案 

2.在專案中,加入[Microsoft.IdentityModel.Clients.ActiveDirectory]的Nuget套件

3.建立一個CDN的控制器

4.把下面的程式碼,放入至這個控制器中

using Newtonsoft.Json;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
using System.Web.Http;

public class CDNController : ApiController
{
    string clientId = "[註冊的應用程式識別碼]";
    string clientSecret = "[金鑰值]";
    string strSubscriptionsId = "[MSDN訂閱代碼]";
    string strResourceGroup = "[CDN節點所在的群組名稱]";
    string strCdnProfile = "[CDN服務名稱]";
    string strCdnEndPoint = "[CDN節點名稱]";
    string strAuthority = "[MSDN訂閱的網域,如maduka.onmicrosoft.com]";

    /// <summary>
    /// 清除CDN快取內容
    /// </summary>
    /// <param name="query">輸入的CDN清除內容JSON物件</param>
    [HttpPost]
    public string PurgeContent(PurgeContentQuery query)
    {
        // 置換設定資料
        string uri = $"https://management.azure.com/subscriptions/{strSubscriptionsId}/resourceGroups/{strResourceGroup}/providers/Microsoft.Cdn/profiles/{strCdnProfile}/endpoints/{strCdnEndPoint}/purge?api-version=2016-10-02";
        string authority = $"https://login.microsoftonline.com/{strAuthority}";

        // 取得AAD的AccessToken
        var authenticationContext = new AuthenticationContext(authority);
        ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
        Task<AuthenticationResult> resultstr = authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientCredential);
        var token = resultstr.Result.AccessToken;

        // 準備呼叫CDN API
        WebClient client = new WebClient();
        client.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
        client.Headers.Add("Content-Type", "application/json");
        string result = "";

        try
        {
            // 執行清理CDN檔案路徑快取的動作
            result = client.UploadString(uri, JsonConvert.SerializeObject(query));
        }
        catch (Exception ex)
        {
            result = ex.Message;
        }

        return result;
    }

    public class PurgeContentQuery
    {
        public List<string> contentPaths { get; set; }
    }
}

這段程式碼,主要是定義一個POST的API,可以讓外面透過API的方式將要清除快取的路徑傳入,然後呼叫Azure REST API進行快取的清除
在呼叫Azure REST API之前,必須先取得Azure AD這個應用程式的AccessToken,並將這個AccessToken放在Header中再進行Azure REST API的叫用

在這裡要注意,必須先在程式碼的最上方,分別把前面步驟記下來的[應用程式識別碼][金鑰],以及相關的資訊填入,以便組合呼叫Azure REST API的路徑用
呼叫Azure REST API路徑的組合,可以參考這個網址https://docs.microsoft.com/zh-tw/rest/api/cdn/endpoints?redirectedfrom=MSDN#Endpoints_PurgeContent

到這裡,程式碼也準備好了,我先上傳一張照片至儲存體帳戶,並透過CDN查看一下檔案是否已經有被CDN服務快取起來

接著我上傳另一張照片,為的就是將來源檔案作一個異動

然後把程式碼執行起來,在Swagger中輸入檔案的路徑JSON內容並執行,可以看到回傳的訊息是200,並且沒有回傳錯誤訊息

最後再重開一次相同的CDN檔案路徑,可以看到照片檔案的快取確實有被更新了

CDN服務對於流量大的網站來說是個不可或缺的角色,透過Azure REST API的叫用,可以很快的進行快取的清除,無需再透過Azure Portal的操作。對於使用CDN服務且檔案內容又常常更新的網站來說,是個非常方便的服務,也可以透過API達到自動化的功能

程式下載
https://github.com/madukapai/maduka-Azure-CDN

參考資料
https://docs.microsoft.com/zh-tw/rest/api/cdn/endpoints?redirectedfrom=MSDN#Endpoints_PurgeContent