さて、前回までに、一通りOneDriveでのファイルへのアクセスの仕方をだらだらと書きましたが、ここから先は、一応上級編です。
何が上級なのかというと、できることがすごくなるのではなく、何気なくやると、危険なことです。
前回の最後にちょろっと書きましたが、今回はリフレッシュトークンを取得して、OneDriveへの常時接続を行います。
先日の例にも書いてありますが、OneDriveで発行するアクセストークンの有効時間は1時間です。
ログイン時に送られてくるJSONに
<expires_in type="number">3600</expires_in>(XML版)
と書いてあるかと思います
なので、1時間おきにアクセストークンの更新が必要なのですが、前回までのResponseType=tokenでは、wl.offline_accessを設定してもリフレッシュトークンは貰えません。
たぶん、貰えません。
リフレッシュトークンを貰うには、以下の方法を行う必要があります。
ResponseTypeをcodeにします。
すると - で繋いだ認証コードが貰えます。
このコードを使ってトークンの要求を行います。
また、これまでと違いClientSecretが必要になったりします。
ここで、重要なことを一つ、
リフレッシュトークンは時間切れになった場合に、アクセストークンを更新するために使います。
リフレッシュトークン と ClientSecret がバレてしまうと、だれでも、どこからでもトークンの更新が出来てしまい、アクセスし放題になってしまいます。
リフレッシュトークンの保存場所にはご注意ください。
同様に、ClientSecretも出来る限りバレない方が良いです。
プログラムに埋め込んで、テキストとして保存しておくのは、危険な感じがします。
PCの所有者が自分のOneDriveに対して何をやっても良いのですが、ウイルス等に感染して、PCがダメになるだけで無く、クラウドのデータまで全て弄られてしまっては大変ですからね?
まぁ、そんな感じで、あたしが作成中のプログラムは、
System.Security.Cryptographyを使って、暗号化してから保存してあります。
まぁ、そう言う意味では暗号用のコードもプログラムに保存してあるって意味では、それも意味が無いと言うことに成ってしまいます。
で、有れば、起動時にユーザーに手入力させるしか無くなるので、それはそれで面倒な感じまします。
この辺りは、ユーザーの利便性とのトレードオフになります。
では早速新しい方法で接続してみましょう。
まず、動作手順をざっと紹介します。
1.リフレッシュトークンがあれば、再接続を試す。新しいトークンが貰えれば4へ
2.Codeでサインインを行う
3.認証コードでアクセストークンの請求を行う
4.リフレッシュトークンを保存する。
5.以下以前同様
注)動作中も、1時間経つ前に、リフレッシュトークンを利用してアクセストークンを更新し続ける必要があります。
実際の送信コード(かなり省略)
まず、リフレッシュトークンを利用して新しいアクセストークンを貰う方法ですが、
String sRes = "https://login.live.com/oauth20_token.srf"
+ "?client_id=" + ClientID
+ "&redirect_uri=" + RedirectURL
+ "&client_secret=" + ClientSecret
+ "&refresh_token=" + sRefresh
+ "&grant_type=refresh_token";
これを以前同様WebClientで送信すれば、リフレッシュトークンが有効であれば、これでJSONが帰ってきます。
JSONをXMLにしたのがこれ
<root type="object">
<token_type type="string">bearer</token_type>
<expires_in type="number">3600</expires_in>
<scope type="string">wl.skydrive_update wl.offline_access wl.signin wl.skydrive</scope>
<access_token type="string"> </access_token>
<refresh_token type="string"> </refresh_token>
<authentication_token type="string"> </authentication_token>
<user_id type="string"> </user_id>
</root>
refresh_tokenはさっさと暗号化して何処か別の所に保存して、生データはメモリ上からは消してしまいましょう。
では、リフレッシュトークンが無かったり、間違っていたり、もしかしたら時間が経ちすぎてリフレッシュトークンが無効になっていた場合はどうするかというと、
上の2.の用に普通にサインインを行います。
細かいところは以前のを参照、
ただし、&response_type=codeの必要があります。
さて、これで、問題なくサインインは出来るので、アクセストークンの様にGetのインラインで認証コードが帰ってきているので、これを取得しましょう。
以前のようなFragmentではなく ?で着いてくるのでe.Url.Queryで認証コードを取得しましょう。
次3番目 トークンの取得
アクセストークン、リフレッシュトークンの取得は上記のアクセストークンの更新同様に
https://login.live.com/oauth20_token.srf
に対して要求をしますが、
若干異なりまして、POSTする必要があります。
これまで、FormのデータをWebClientでPOSTすることはありませんでしたので、その方法を書きます。
まず、
パラメータはSystem.Collections.Specialized.NameValueCollectionに入れる必要があります。
これは、普通に宣言して、
System.Collections.Specialized.NameValueCollection nvcData = new System.Collections.Specialized.NameValueCollection();
nvcData.Add("client_id", ClientID);
nvcData.Add("redirect_uri", RedirectURL);
nvcData.Add("client_secret", ClientSecret);
nvcData.Add("code", AuthCode);
nvcData.Add("grant_type", "authorization_code");
wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
bRecivedata = wc.UploadValues("https://login.live.com/oauth20_token.srf", "POST", nvcData);
これで、トークンが取得出来ます。
トークンの形式は上のリフレッシュの時と同じ
リフレッシュトークンは、1時間経過してアクセストークンの有効期限が切れるまで必要ないので何処かに大事にしまっておいてください。
以下は、これまで同様アクセストークンを使ってアクセスすればOKです。
これで、OneDriveのオリジナルクライアントが作れますね☆
Windows7までの全てダウンロードしないと同期が取れなかったり、
Windows8の様にMSアカウントでサインインしないとOneDriveが使えなかったりとか
そう言った問題からも解消されますし、
別のディレクトリ、別のドライブ、別のPCに入っている、それぞれのディレクトリだけを個別に同期を取ったりすることも出来る様になります。
まぁ、あたしが目指しているのはこれです。
サーバーに入っているデータをバックアップする、
PC1に入っているデータをバックアップする。
PC2に入っているデータをバックアップする。
これって、全ファイル同期だと、結局全部のPCに全部のデータが入るだけですし、意味が無いですよね。
ソフトが出来たら、そのうちVectorに上げます。 |