For a member only area I would like to secure (private) assets:

  • The files should not be accessible when not logged in
  • The file download URL should be randomly generated and should expire after some time OR the files can be placed above the web root

There is for example Link Vault for ExpressionEngine which is able to achieve that.


I ran into this requirement today and initially assumed a plugin would be required, but then I spotted that the native Assets action menu already included a Download File option and it was working just fine with files that weren’t publicly accessible. Maybe we could use that rather than reinventing the wheel?

If you check DownloadFileElementAction.php you can see the markup and JS that’s used for this button in the control panel. It generates a simple <form> tag that POSTs to assets/downloadAsset. With a tiny bit of tweaking that can be converted to a code suitable for use in a frontend template:

<form method="post" target="_blank" action="">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="assets/downloadAsset" />
    <input type="hidden" name="assetId" value="123" />
    <input type="submit" value="Submit" />

This works a treat and includes all native permissions checks as you’d expect. So long as the requesting user has the viewAssetSource permission for the Asset Source the download will work. If the requesting user is logged out then they are automatically redirected to your loginPath.

The only snag I’ve noticed is that Craft does return a JSON formatted error string if your user doesn’t have permission to view the asset. In my case this doesn’t matter, as all authenticated users will have permission to view the files - we’re just trying to prevent guests from seeing them.

Since this approach requires POSTs it’s a bit limiting (secured img tags are a non-starter), but for typical download button use cases it looks fine to me and avoids the need for third party plugins.

(This is a Craft 2 build, I haven’t tested this with Craft 3)

  • In Craft 3, your action would just be assets/download-asset instead of assets/downloadAsset. – Matt Stein Dec 29 '17 at 5:47

There is a plugin from Jeroen Kenters called Member Assets which denies access when logged out.

If you really need a random url, you could extend his plugin.

  • Thanks! The random url is not needed if the asset can be outside of the web root. But this plugin works only where you can specify how the asset is retrieved (e.g. in your own template). It will not work for example when linking to an image asset in a rich text field. – Lars Bilke Jul 8 '14 at 12:18
  • You could add the link directly into your fields using the reference tag: buildwithcraft.com/docs/reference-tags or by entering the id directly /memberassets/150. – Victor In Jul 8 '14 at 12:27
  • Yes thats possible but not that client friendly. But thanks anyway! – Lars Bilke Jul 8 '14 at 12:45
  • You could write a custom redactor plugin, or replace the normal asset link with the secure one in your template. – Victor In Jul 8 '14 at 12:49

There is now the Internal Assets Plugin which allows to place assets above the web root and works as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.