Open macintoshhelper opened 3 years ago
@macintoshhelper hey, did you ever get WebCrypto signing working?
I spent a bunch of hours trying to write a signature function to use with your fork, but I could never get the signature to validate..
This is the non-working code I ended up with:
import OAuth from 'oauth-1.0a';
const CALLBACK_URL = "https://localhost:3000/oauth/callback";
const encoder = new TextEncoder();
async function signData(baseString: string, keyString: string) {
return await crypto.subtle.importKey(
'raw',
encoder.encode(keyString),
{ name: 'HMAC', hash: 'SHA-1' },
false,
['sign']
).then(key => {
return crypto.subtle.sign(
"HMAC",
key,
encoder.encode(baseString)
);
}).then(signature => {
let b = new Uint8Array(signature);
// base64 digest
return btoa(String.fromCharCode(...b));
});
}
export async function getRequestToken(consumerKey: string, consumerSecret: string) {
const url = "https://www.flickr.com/services/oauth/request_token";
const token = {
key: consumerKey,
secret: consumerSecret
}
const oauth = new OAuth({
consumer: token,
signature_method: 'HMAC-SHA1',
hash_function: signData,
});
const requestData = {
url,
method: 'GET',
data: {
oauth_callback: CALLBACK_URL
}
};
const authorisedRequest = await oauth.authorizeAsync(requestData, token);
let params = new URLSearchParams();
for (let [key, value] of Object.entries(authorisedRequest)) {
params.append(key, value as string);
}
const response = await fetch(requestData.url + `?${params}`, {
method: requestData.method,
});
const body = await response.text();
const parsedBody = oauth.deParam(body);
return parsedBody;
}
I've got this working with following code and pull request #118
const oauth = new OAuth({
consumer: {
key,
secret
},
signature_method: 'HMAC-SHA256',
async hash_function(baseString, key) {
// encoder to convert string to Uint8Array
var enc = new TextEncoder();
const cryptKey = await crypto.subtle.importKey(
'raw',
enc.encode(key),
{ name: 'HMAC': hash: 'SHA-256' },
false,
['sign', 'verify'],
)
const signature = await crypto.subtle.sign(
{ name: 'HMAC': hash: 'SHA-256' },
cryptKey,
enc.encode(baseString)
)
let b = new Uint8Array(signature);
// base64 digest
return btoa(String.fromCharCode(...b));
}
})
const auth = await oauth.authorize(
{
method: method.toUpperCase(),
url,
},
{
key: this.options.accessToken,
secret: this.options.tokenSecret
}
)
Hi, WebCrypto usage will generally require the usage of asynchronous APIs. The
oauth.authorize
function does not support promises for the signature hash function.I've opened a PR over at #107 which should resolve this, and after that, documentation could be added to the README for a WebCrypto example to replace the CryptoJS, potentially resolving #97