問題
メディアサイトで、記事公開と同時にFacebookで拡散を促すため、投稿の予約機能を活用することがあると思います。しかし投稿予約時にはまだ記事が公開されていないので、通常であればOGPが表示されません。ここではその解決方法について説明します。
解決策
仕組みは単純で、Facebookのクローラーからのみアクセスを許可します。
Facebookクローラーのドキュメントを見てみると、Facebookのクローラーが使用するIPアドレスの取得方法が記述してあります。合わせてUser Agentも載ってはいるのですが、こちらは偽装出来るため今回は使用しません。
実装
Gemfile
gem 'irrc'
gem 'ipaddr_range_set'
app/controllers/application_controller.rb
def authenticate_facebook_ogp!
# Facebbok Crawlerからのアクセスのみを許可
# ref: https://developers.facebook.com/docs/sharing/webmasters/crawler#access
client = Irrc::Client.new
client.query(:jpirr, 'AS32934', source: :radb, protocol: :ipv4)
result = client.perform
ip_ranges = result['AS32934'][:ipv4]['AS32934']
range = IPAddrRangeSet.new *ip_ranges
raise ActiveRecord::RecordNotFound unless range.include? request.remote_ip
end
使い方
app/controller/articles_controller.rb
def show
authenticate_facebook_ogp! if @article.released_at > Time.now
end
注意
今回の方法でFacebookクローラーからのアクセスを許可した場合、他のユーザが同じようにFacebook上でURLを入力した場合にも、OGPが取得されてしまいます。よって絶対に公開したくないページに関しては、今回の方法を用いることは出来ませんのでご注意。
(みなさんどうしてますか… ( _ _) URLを推測不可能なものにするとか、外部サービス使うとか、期間限定でアクセス許可してOGPキャッシュ更新しておくとか…?)