How to Secure RSS Feed for Paid Content in Rails 5

To create a URL for the paid episodes that users can access: https://rubyplus.com/episodes/paid.rss, you have to define the endpoint in the routes.rb:

resources :episodes 
   collection do
     get :paid
   end
end

Now, define a paid action in episodes controller:

def  paid
  @episodes = Episode.published.paid.order('position desc')

  respond_to do |f|
    f.rss { render action: :index }
  end
end

The published and paid methods are implemented in episode model.

def self.published
  where('published_at <= ?', Time.now.utc)
end

def self.paid
  where(paid: true)
end

The app/views/episodes/index.rss.builder looks like this:

title = "Rails Screencasts"
author = "Bala Paranj"
description = "Learn practical tips and techniques on how to develop web applications using Ruby on Rails web framework. The episodes are short to minimize the amount of content to avoid overwhelming learners. The episodes are designed to give developers a quick way to get their feet wet and learn by building web apps."
keywords = "rails, ruby on rails, screencasts, podcasts, tips, tricks, tutorials, training, programming,, web application framework"
ext = 'mp4'

xml.rss :version => "2.0", "xmlns:itunes" => "http://www.itunes.com/dtds/podcast-1.0.dtd",  "xmlns:media" => "http://search.yahoo.com/mrss/", "xmlns:atom" => "http://www.w3.org/2005/Atom" do
  xml.channel do
    xml.tag!("atom:link",  "href"=>"https://rubyplus.com/episodes.rss", "rel"=>"self", "type"=>"application/rss+xml") 
    xml.title title
    xml.link 'https://www.rubyplus.com'
    xml.description description
    xml.language 'en'
    xml.pubDate @episodes.first.created_at.to_s(:rfc822)
    xml.lastBuildDate @episodes.first.created_at.to_s(:rfc822)
    xml.itunes :author, author
    xml.itunes :keywords, keywords
    xml.itunes :explicit, 'clean'
    xml.itunes :image, :href => "http://rubyplus.com/images/RAILS-res-3000px-winning-purple.png"
    xml.itunes :owner do
      xml.itunes :name, author
      xml.itunes :email, 'feedback@rubyplus.com'
    end
    xml.itunes :block, 'no'
    xml.itunes :category, :text => 'Technology' do
      xml.itunes :category, :text => 'Software How-To'
    end
    xml.itunes :category, :text => 'Education' do
      xml.itunes :category, :text => 'Training'
    end

    @episodes.each do  |episode|
      xml.item do
        xml.title episode.title
        xml.description episode.description
        xml.pubDate episode.created_at.to_s(:rfc822)
        xml.enclosure :url => "http://rubyplus.com/download/episode?id=#{episode.id}", :length => episode.file_size, :type => 'video/mp4'
        xml.link episode_url(episode)
        xml.guid({:isPermaLink => "false"}, episode.permalink)
        xml.itunes :author, author
        xml.itunes :subtitle, truncate(episode.description, :length => 150)
        xml.itunes :summary, episode.description
        xml.itunes :explicit, 'no'
        xml.itunes :duration, episode.duration
      end
    end
  end
end

This template is stolen from Ryan Bates project. This is Rails built-in feature. We don't need any gems. In devise.rb, uncomment:

config.http_authenticatable = true

to turn on HTTP authentication in the controller. In the episodes controller, you must have the before action to authenticate the user for access to paid only RSS feed:

before_action :authenticate_user! , only: [:paid]

That's it. Now the subscribers will be able to access your paid RSS feed using the credentials on your site. It's easy to use basic authentication to secure feeds in Rails 5 with Devise gem.


Related Articles