Last active
May 16, 2017 02:16
-
-
Save neetsdkasu/19f9703f8167213708f751c1c2347599 to your computer and use it in GitHub Desktop.
【練習】ツイッターで認証やってみた(仮コード)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// test | |
// author: Leonardone @ NEETSDKASU | |
open neetsdkasu.Twitter | |
let consumerToken = { | |
Key = "key"; | |
Secret = "secret" | |
} | |
let oauthToken = { | |
Key = "key"; | |
Secret = "secret" | |
} | |
let pinCode = "0000000" | |
[<EntryPoint>] | |
let main _ = | |
use client = new Client(consumerToken, "oob") | |
// match OAuth.requestToken client with | |
match OAuth.accessToken client oauthToken pinCode with | |
| Some(s) -> printfn "%s" s | |
| None -> printfn "failed" | |
0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// author: Leonardone @ NEETSDKASU | |
namespace neetsdkasu.Twitter | |
type Token = { Key: string; Secret: string } | |
type Client(consumerToken: Token, callback: string) = | |
do | |
System.Net.ServicePointManager.SecurityProtocol | |
<- System.Net.ServicePointManager.SecurityProtocol | |
||| System.Net.SecurityProtocolType.Tls12 | |
let webClient = new System.Net.WebClient() | |
let encoded_callback = System.Net.WebUtility.UrlEncode(callback) | |
member this.Callback = encoded_callback | |
member this.ConsumerToken = consumerToken | |
member this.WebClient = webClient | |
interface System.IDisposable with | |
member this.Dispose() = webClient.Dispose() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Twitter.OAuth | |
// author: Leonardone @ NEETSDKASU | |
namespace neetsdkasu.Twitter | |
module OAuth = | |
let param name value = (name, value) | |
let toOAuthParam = | |
(+) "OAuth " | |
<< String.concat ", " | |
<< List.map (function | |
(k, v) -> | |
k + "=\"" + Utility.percentEncode v + "\"" | |
) | |
let requestTokenApi = "https://api.twitter.com/oauth/request_token" | |
let requestToken (client: Client) = | |
let param = [ param "oauth_consumer_key" client.ConsumerToken.Key | |
; param "oauth_nonce" (Utility.nonce()) | |
; param "oauth_signature_method" "HMAC-SHA1" | |
; param "oauth_timestamp" (string <| Utility.now() + 10u) | |
; param "oauth_version" "1.0" | |
; param "oauth_callback" client.Callback | |
] | |
let signature = Utility.signature | |
"POST" requestTokenApi param | |
client.ConsumerToken.Secret "" | |
let oauthParam = toOAuthParam (("oauth_signature", signature) :: param) | |
do client.WebClient.Headers.Add("Authorization", oauthParam) | |
try | |
let res = client.WebClient.UploadData(requestTokenApi, Array.empty) | |
Some(System.Text.Encoding.ASCII.GetString(res)) | |
with | |
ex -> | |
eprintf "%A" ex | |
None | |
let accessTokenApi = "https://api.twitter.com/oauth/access_token" | |
let accessToken (client: Client) oauthToken pincode = | |
let param = [ param "oauth_consumer_key" client.ConsumerToken.Key | |
; param "oauth_nonce" (Utility.nonce()) | |
; param "oauth_signature_method" "HMAC-SHA1" | |
; param "oauth_timestamp" (string <| Utility.now() + 10u) | |
; param "oauth_version" "1.0" | |
; param "oauth_token" oauthToken.Key | |
; param "oauth_verifier" pincode | |
] | |
let signature = Utility.signature | |
"POST" accessTokenApi param | |
client.ConsumerToken.Secret oauthToken.Secret | |
let oauthParam = toOAuthParam (("oauth_signature", signature) :: param) | |
do client.WebClient.Headers.Add("Authorization", oauthParam) | |
try | |
let res = client.WebClient.UploadData(accessTokenApi, Array.empty) | |
Some(System.Text.Encoding.ASCII.GetString(res)) | |
with | |
ex -> | |
eprintf "%A" ex | |
None | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Twitter.Utility | |
// author: Leonardone @ NEETSDKASU | |
namespace neetsdkasu.Twitter | |
module Utility = | |
let percentEncode s = | |
System.Uri.EscapeDataString(s) | |
|> String.collect (fun c -> | |
match c with | |
| '!' | '*' | '\'' | '(' | ')' -> System.Uri.HexEscape(c) | |
| _ -> string c | |
) | |
let base64 barr = System.Convert.ToBase64String(barr) | |
let toBytes (s: string) = System.Text.Encoding.ASCII.GetBytes(s) | |
let nonce() = | |
use rng = new System.Security.Cryptography.RNGCryptoServiceProvider() | |
let arr : byte array = Array.zeroCreate 32 | |
do rng.GetBytes(arr) | |
base64 arr | |
|> String.collect (fun c -> | |
if System.Char.IsLetterOrDigit(c) then | |
string c | |
else | |
"" | |
) | |
let now = | |
let baseDate = new System.DateTime(1970, 1, 1) | |
fun () -> | |
(System.DateTime.UtcNow - baseDate).TotalSeconds | |
|> uint32 | |
let genSignatureBaseString mthd api param = | |
let paramStr = | |
param | |
|> List.map (function | |
(k, v) -> (percentEncode k, percentEncode v) | |
) | |
|> List.sortBy fst | |
|> Seq.map (fun s -> fst s + "=" + snd s) | |
|> String.concat "&" | |
|> percentEncode | |
percentEncode mthd + "&" + percentEncode api + "&" + paramStr | |
let getSigningKey key1 key2 = | |
percentEncode key1 + "&" + percentEncode key2 | |
let signature mthd api param key1 key2 = | |
let signatureBaseString = | |
toBytes <| genSignatureBaseString mthd api param | |
let signingKey = | |
toBytes <| getSigningKey key1 key2 | |
use crypto = new System.Security.Cryptography.HMACSHA1(signingKey) | |
crypto.ComputeHash(signatureBaseString) | |
|> base64 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Twitter.Utlity test | |
// author: Leonardone @ NEETSDKASU | |
#load "Twitter.Utility.fsx" | |
open neetsdkasu.Twitter | |
let tuple name value = (name, value) | |
// Creating a signature | |
// https://dev.twitter.com/oauth/overview/creating-signatures | |
let param = [ tuple "status" "Hello Ladies + Gentlemen, a signed OAuth request!" | |
; tuple "include_entities" "true" | |
; tuple "oauth_consumer_key" "xvz1evFS4wEEPTGEFPHBog" | |
; tuple "oauth_nonce" "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg" | |
; tuple "oauth_signature_method" "HMAC-SHA1" | |
; tuple "oauth_timestamp" "1318622958" | |
; tuple "oauth_token" "370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb" | |
; tuple "oauth_version" "1.0" | |
] | |
let consumerSecret = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw" | |
let oauthTokenSecret = "LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE" | |
let signatureBaseString = "POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521" | |
let signingKey = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE" | |
let oauthSignature = "tnnArxj06cWHq44gCs1OSKk/jLY=" | |
let api = "https://api.twitter.com/1/statuses/update.json" | |
do | |
let sbs = Utility.genSignatureBaseString "POST" api param | |
if sbs = signatureBaseString then | |
printfn "signatureBaseString is OK" | |
else | |
printfn "%s" sbs | |
let sk = Utility.getSigningKey consumerSecret oauthTokenSecret | |
if sk = signingKey then | |
printfn "signingKey is OK" | |
else | |
printfn "%s" sk | |
let signature = Utility.signature "POST" api param consumerSecret oauthTokenSecret | |
if signature = oauthSignature then | |
printfn "signature OK" | |
else | |
printfn "%s" signature | |
;; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
コードの色付けのためだけにGist上では拡張子をfsxにしてるぽ