Created
February 17, 2022 03:27
-
-
Save CraigglesO/57f0c190a88cae316791225ecbfd5ef9 to your computer and use it in GitHub Desktop.
PUT signedURL for clients without threat of bad actors
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
import { AwsClient } from 'aws4fetch' | |
let b2 | |
// accessKeyId -> B2 keyID | |
// secretAccessKey -> B2 AppKey | |
export const prepB2 = (accessKeyId, secretAccessKey) => { | |
if (!b2) b2 = new AwsClient({ accessKeyId, secretAccessKey, service: 's3' }) | |
} | |
export const createSignedURL = async (path, contentLength, contentType, contentEncoding, cacheControl) => { | |
// NOTE: i replaced bucket and endpoint. you can set these how you want | |
// bucket is the NAME of your bucket not your bucket id | |
// endpoint will be something is like "s3.us-west-000.backblazeb2.com" | |
const location = new URL(`https://{{bucket}}.{{endpoint}}/${path}`) | |
// MUST put a content length. This is crucial to not allow bad actors to put whatever they want at the key | |
if (!contentLength) return { err: 'Missing contentLength.' } | |
if (!contentType) return { err: 'Missing contentType.' } | |
const signHeaders = new Headers() | |
signHeaders.set('Content-Length', contentLength) | |
signHeaders.set('Content-Type', 'application/json') | |
if (contentEncoding) signHeaders.set('Content-Encoding', contentEncoding) | |
if (cacheControl) signHeaders.set('Cache-Control', cacheControl) | |
const signedRequest = await b2.sign(location, { | |
method: 'PUT', // if not supplied, will default to 'POST' if there's a body, otherwise 'GET' | |
headers: signHeaders, // standard JS object literal, or Headers instance | |
// body, // optional, String or ArrayBuffer/ArrayBufferView – ie, remember to stringify your JSON | |
aws: { | |
signQuery: true, // set to true to sign the query string instead of the Authorization header | |
appendSessionToken: true, // set to true to add X-Amz-Security-Token after signing, defaults to true for iot | |
allHeaders: true // set to true to force all headers to be signed instead of the defaults | |
} | |
}).catch(() => null) | |
if (!signedRequest) return { err: 'Failed to sign request.' } | |
const { method, url, headers } = signedRequest | |
return { method, url, headers: [...headers] } | |
} | |
// CLIENT/BROWSER SIDE added for posterity: | |
function clientBrowserSideCode () { | |
const { method, url, headers } = res | |
await fetch(url, { method, body, headers }) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment