Generate expiring urls for Amazon S3 via a WordPress Plugin

I am a .net developer and haven’t done any PHP work ever. But i use WordPress and for some time now i been looking for a plugin that could generate a URL for Amazon S3 that is “signed” and will expire after a certain amount of time.

I posted the question on both wordpress and amazon forums but haven’t got any replies. Well .. maybe i did not explain my problem good or nobody else is interested in this.

So i figured i had to take care of this myself. And as i said. I’m a total newbie in both PHP and WordPress plugins so my plugin is probably really really stupid and i would be happy if somebody could send suggestions how to make it better. But it works.

How does it work?

You just add

[S3 bucket=yourbucket text=your link text]the_object_name.txt[/S3]

to your post or page and it will generate a expiring urls that no leecher can link to. If you don’t supply and link text it will not generate a link and just print the URL. I use the same bucket names as URL’s (like netplay.whoa.nu) and if you use Amazon standard urls you must change this.

Download: Amazon S3 URL Generator

Thanks to this guy for the PHP script i based this on.

41 Thoughts on “Generate expiring urls for Amazon S3 via a WordPress Plugin

  1. This seems pretty promising. A few questions:

    –So this actually puts the “safe” links on the WP page or post, generating it on the fly based on the object name/path?

    –Where are you saving the access key and the secret key? Amazon says they are supposed to be saved and worked with on a secure server so that nobody can ever learn your secret key. I’d want to make sure of the safety of this before I tried your plugin.

    –Does your plugin allow for alteration of the expiration time?

  2. Hi Mark!

    1. Yes, it generates a “safe” url so that you can put your object in a bucket to “read only”.

    2. I store it with the regular “Save options” thing in wordpress. I suppose it stores it in clear text in the DB. But i don’t really know exactly how that works. I guess i should use some kind of encryption for it.

    3. Yes, you can set the expiration time in an option in WordPress.

    And as i say in the post, I’m no PHP developer so i pretty much “freestyled” this plugin because i was desperate for one. I do not guarantee anything really, but i wanted to share it so someone else in the same situation as me could use it.

  3. If you check out this URL

    http://www.fused.org.uk/2008/08/s3-query-string-authentication-generator/

    It was the script i used to actually generate the URLs. If you just have access to some sort of PHP server you can just run the script once to generate a url that works for X number of days and then you can remove your key and stuff from the file .. should work in this scenario.

  4. Thanks for the info. I guess, then, that my two main considerations are the encryption/security issue, and the fact that I am looking to create these URLs for subscribers to my mailing list to get a free download, which means I don’t want them published on my site at all. I suppose I could just have a draft post that only I use myself to generate the URLs — your plugin so far seems to be my best bet for creating the URLs at all without hiring a programmer! Which then brings it all back to the encryption issue. If your plugin stored the Secret Key in a way that ensure its safety, I’d probably be all over it!

  5. It was actually at that page that I found out about your plugin.

    Obviously PHP is running in my hosting account, since I run WordPress. I’d thought of that myself, just running and wiping things out so the Secret Key never really resided anywhere for long. Seems a little tedious, but probably better than no solution at all. Food for thought.

    Meantime, I’ll keep an eye out for anytime you might add encryption to the plugin. Thanks again for the conversation.

  6. I just gave your plugin a shot. Figured I could take the same approach with your plugin — just remove the key after creating a URL. Got some URLs generated, but they didn’t work. Error said:

    “SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method.”

    I confirmed that I had the proper 2 keys entered and saved in the specs. Any thoughts?

  7. Hmm, don’t know really. What URL did you use on the bucket attribute? I use my dns names and it works fine for me. I maybe can have a look on it tommorow and see what i can find.

    I’m drinking beer right now and is going to Thailand on Sunday, but will have a quick look tommorow!

  8. Thanks for helping out, whenever your can :)

    I quickly realized that just putting in the bucket name alone where your code asks for it was not enough for a proper URL, so I put the whole root address. For a file called test.txt in a bucket called theoffhandband I put in the following code in my post:

    [S3 bucket=theoffhandband.s3.amazonaws.com text=Test]test.txt[/S3]

    There’s nothing wrong with the URL. I temporarily set the file to be Readable by everyone, and I was able to access it no problem with http://theoffhandband.s3.amazonaws.com/test.txt in my browser, and then when I set the permissions back, it went Access Denied again.

    So it appears there’s something wrong with the query-string-authentication URL only, and in particular according to that error something wrong with the calculation of the signature.

    Thanks again for your help!

  9. im getting the same error as mark s….

    SignatureDoesNotMatch

    The request signature we calculated does not match the signature you provided. Check your key and signing method.

  10. Hmm .. i guess i have to take a look at that. I think it is because i use custom urls. Will test it without custom url and see if i get the same error later.

  11. How can this script even work?
    You just sign the simple request “GETnnn{$expires}n/{$bucket}/{$resource}”
    But when you click on a link in e.g. FireFox the GET request will have lots of other information like Host, User-Agent, Accept-* etc.
    The signed request will not be near the same as the actual request sent.

    Has anyone got it working with private files?

  12. RaiulBaztepo on March 28, 2009 at 10:03 pm said:

    Hello!
    Very Interesting post! Thank you for such interesting resource!
    PS: Sorry for my bad english, I’v just started to learn this language ;)
    See you!
    Your, Raiul Baztepo

  13. Wonderful site. hope to come back again soon,,

  14. WongWay on July 8, 2009 at 8:07 am said:

    I am looking for a solution to deliver content and avoid hotlinking to S3. I was really hoping this is working but it is not for me. Has anyone been successful or found other solutions that don’t cost developer time and money?

  15. I’m sorry but i don’t know why it doesn’t work for you guys. It works fine for me ..

    I really do not have any time to fix this but would love if some skilled PHP developer could make a new and improved version of this.

  16. Another option to consider is S3FlowShield. It is a commercial plugin that does what is described in this post and more. The developer is continually adding features and is very responsive to support requests and questions.

    http://www.s3flowshield.com

    Wes

  17. Markus on March 11, 2010 at 8:03 pm said:

    Hi,

    Works in WordPress 2.9.2?

    Thanks.

  18. Thanks very much for taking your time to create this very useful infos

  19. Hi Ola, great work for a first WordPress plugin.

    The reason this is not working for users (like myself) who use the standard S3 bucket names like BUCKETNAME.s3.amazonaws.com is that only BUCKETNAME should be in the $string_to_sign, not the entire BUCKETNAME.s3.amazonaws.com . For people using CNAMES for their S3 buckets, like s3.MYDOMAIN.COM , the entire s3.MYDOMAIN.COM needs to be in $string_to_sign.

    The simplest fix is to change line 30 from:

    $string_to_sign = “GETnnn{$expires}n/{$bucket}/{$resource}”;

    to:

    $string_to_sign = “GETnnn$expiresn/”.str_replace(‘.s3.amazonaws.com’, ”, $bucket).”/$resource”;

    This should work for both standard S3 bucket names and CNAMES.

  20. Thanks!

    I have updated it now to version 0.6 and hopefully it resolves the issues people have had.

    If you have more suggestions and changes i would be glad to add you as a developer on the plugin :)

  21. Hey guys.

    Thanks for this plugin. Good work :)

    But… I have a little problem with it.

    I typed in:
    [S3 bucket=domainname text=Download]amazon.rar[/S3] and it redirects to domainname/amazon.rar?AWSAccessKeyId=and stuff like that…

    What am I doing wrong :( ?

  22. Alex, use:

    [S3 bucket=BUCKETNAME.s3.amazonaws.com text=Download]amazon.rar[/S3]

    where BUCKETNAME is the name of the bucket you created in your Amazon S3 account

  23. I love the plugin works great!! Much easier to work with, but I am a big WordPress guy so I prefer to do everything in WordPress…So agin thank you!

    @chrisegg

  24. I have no idea actually. Would be great if you could try it and report here if it works or not!

  25. podo on July 14, 2010 at 7:07 am said:

    Hi!

    Could you tell me, if it works with Amazon CloudFront?

  26. podo on July 16, 2010 at 7:07 am said:

    Um, I’ve tested, but it doesn’t. Anyway, thanks for great plugin!

  27. Pee Jay Latombo on August 9, 2010 at 3:08 pm said:

    Plugin is not working at all:

    http://www.internettraininglab.com/rolodex/

    Below that page is an anchor text “your link text”

    Thanks for you help.

  28. Just a quick FYI, using this without CNAME actually just posts the complete Bucket URL, unmasked, right there in the browser with just a bunch of string text behind it.

    It will be easy for some to just figure out all they have to do is grab the actual link out of the string, and hotlink it all day.

    CNAME’s may be the only way to make sure it’s secure.

  29. Beau:

    You need to remove public access on the file at Amazon…

  30. Sandor on March 6, 2011 at 6:03 pm said:

    Hi,

    this is super idea. How can I use the plugins link generator in video streaming plugins, e.g. Hana Player?

    Can I write the shortcode into a video streaming plugin?

  31. What about using directories though?

    [S3 bucket=yourbucket text=your link text]dir1/the_object_name.txt[/S3]

    Doesnt work when using the slash, and neither do any additional directories including forward slashs’s

    [S3 bucket=yourbucket text=your link text]dir1/dir2/the_object_name.txt[/S3]

    Im sure its a very easy fix.. or you could as well make a new “dir” parameter alongside bucket/text… but then sitll need to resolve using forward slash with directory regardless..

    Although, when using %2F to represent the slash, it seems to work fine. But %2F is not desirable as / is what we’re looking for :)

  32. Great plugin, works fine for protected downloads.

    I like to use it also for protected video with a Flowplayer plugin. But than you get a plugin within a plugin as you have to specify the video URL inside the flowplayer shortcode. That doesn’t work.

    Do you have an idea how to make this plugin work play (protected) video on my site?

  33. AstebyObses on July 16, 2011 at 7:26 am said:

    [URL=http://buyprovigil.yuku.com]purchase provigil[/URL]

  34. I’ve spent my entire day trying to get my videos to stream from my S3 account the way I wanted and then realized they weren’t protected! So I thought this would do the trick, but no matter what I do, it just won’t work.

  35. Will this plugin also work to do the same thing with files that are on a different server (not Amazon S3)? Thanks in advance…

  36. I like this plugin, but my AWS Access Key is in the URL string. I’m uncomfortable with this. Does this happen for anyone else or is it something I’m doing wrong?

  37. Has anyone got this working? I, too, am getting the “ SignatureDoesNotMatch” message.

  38. Not working

  39. Hi,

    If you didn’t find the answer yet, you can check youtube.com or google.com. They will provide more answers in your questions. Check this out Dub Turbo Beat Maker Software.

  40. I had some trouble with this until I realized I was entering the “bucketname” incorrectly.

    Incorrect = “s3.amazonaws.com/BUCKET”
    Correct = “BUCKET.s3.amazonaws.com”

    Thanks for creating this!

  41. i would like to know the solution for using directories as well
    anyone with directories in amazon bucket got this to work ?

Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Post Navigation