Last active
October 6, 2017 10:31
-
-
Save johnmeehan/b587510798286486d612b655e8a168b4 to your computer and use it in GitHub Desktop.
Obfuscated Download Links - How to add an obfuscated download link to a downloadable attachment.
This file contains hidden or 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
# Rails side: | |
# 1. Attachment.rb model needs a token method that encrypts the model id. | |
class Attachment < ActiveRecord::Base | |
mount_uploader :file, AttachmentUploader | |
# Add this | |
def self.find_by_token(token) | |
begin | |
find(UrlParamEncryptor.decrypt(token)) | |
rescue UrlParamEncryptor::DecryptionError | |
raise ActiveRecord::RecordNotFound | |
end | |
end | |
def file_name | |
File.basename(file.path) | |
end | |
def file_path | |
file.path | |
end | |
def file_url | |
file.url | |
end | |
# Add this | |
def token | |
UrlParamEncryptor.encrypt(id) | |
end | |
end | |
This file contains hidden or 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
// 4 . Attachment.ts model - add `downloadUrl: string` and `token: string` | |
export class Attachment { | |
id: number; | |
fileName: string; | |
originalFileName: string; | |
filePath: string; | |
fileUrl: string; | |
fileItem: Object; | |
contentType: string; | |
downloadUrl: string; | |
token: string; | |
@DateAttr updatedAt: moment.Moment; | |
} |
This file contains hidden or 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
# lib/warden/attachment_download_strategy.rb | |
# Authenticates the download token | |
# success: returns the attachment object requested. | |
module Warden | |
module Strategies | |
class AttachmentDownloadStrategy < ::Warden::Strategies::Base | |
def valid? | |
attachment_token | |
end | |
def authenticate! | |
attachment = Attachment.find_by_token(attachment_token) | |
attachment.nil? ? fail!('strategies.attachment_download_strtegy.failed') : success!(attachment) | |
end | |
private | |
def attachment_token | |
params['attachment_token'] | |
end | |
end | |
end | |
end | |
Warden::Strategies.add(:attachment_download_strategy, Warden::Strategies::AttachmentDownloadStrategy) |
This file contains hidden or 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
<!-- Displaying the links --> | |
<li *ngFor="let attachment of $attachments | async" | |
class="attachments__item"> | |
<a | |
class="attachments__item-link" | |
download-file | |
target="_blank" | |
[href]="downloadUrl(attachment)"> | |
{{attachment.originalFileName}} | |
</a> | |
<a | |
title="Remove" | |
confirm="Are you sure you want to remove this document?" | |
class="attachments__remove-item btn-icon--times btn-icon--secondary" | |
(confirmed)="removeAction(attachment)"> | |
</a> | |
</li> |
This file contains hidden or 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
// 5 | |
//Angular side: | |
// Attachmet_list.ts ( the component that iterates over the attachments ) add `downloadUrl()` | |
// Use this url in the view for the user to click on. | |
export class AttachmentsComponent { | |
$attachments = this._service.$attachments; | |
downloadUrl(attachment) { | |
return `/attachments/${attachment.token}`; | |
} | |
} | |
This file contains hidden or 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
# 2. Attachment Serializer needs to now pass this `:token` | |
# attachment_serializer.rb | |
class AttachmentSerializer < ActiveModel::Serializer | |
attributes :id, :file_name, :file_path, :file_url, :original_file_name, | |
:content_type, :updated_at, :token | |
end |
This file contains hidden or 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
# 3. Attachment Controller | |
# We need to find the attachment by the token | |
# We can use a Warden Strategy to validated the link and set the id without having to go through the entire rails app. | |
#attachments_controller.rb | |
before_action :set_attachment, only: [:show, :destroy] | |
private | |
def set_attachment | |
@attachment = warden.authenticate!(scope: :attachment) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment