Herokuで公開しているサービスに独自ドメインをサブドメインなしで設定する(ムームードメインの場合)
railsで作成したアプリケーションをHerokuを使って公開する時に、ムームードメインで取得したドメインをサブドメインなしで設定しようとしたのですが、ムームードメインを使ってやっている記事が見つからなかったので簡単にまとめておきます。
Heroku側の設定
⑴まず、Herokuのダッシュボードからドメインを設定したいアプリケーションのSettings画面に行く。
⑵ Settings画面で少しスクロールすると、Domains and certificatesみたいな欄があるので、 そこでAdd Domainをクリックして、出てきたフォームに自分が設定したいドメインを入力する。
(例)example.comみたいにhttps://無しで記述する。
⑶ そうしたらsave changesする。
⑷すると下の方の Domain Nameのところに先ほど追加したドメインが表示されているはずです。 ドメインが追加されていることが確認できたら、Domain Nameの右にあるDNS Targetをコピーします。
DNS Targetは、[ランダムな文字列].herokudns.comみたいになってるはず。
ムームードメイン側の設定
すると、左側のサイドバーの一番上にドメイン操作とあるはずなのでそれをクリックして、
この時点で、自分が取得しているドメインの一覧が出てくるはずです。(出てこない場合はページに記載されている指示通りに進めると表示されるようになります。)
⑶その後、設定したいドメインの処理の欄にある変更ボタンをクリックする。
すると、「カスタム設定のセットアップ情報変更」と書かれたページに行くので、そのページの設定2のサブドメインを空、種別をALIAS、内容に先ほどコピーしたDNS Targetをペーストします。優先度も空にして、
⑷セットアップ情報変更をクリックしたらこれで全ての設定が終了です!
僕の場合は、その後2分ほどでHerokuにドメインが反映されて、接続できるようになりました。 人によって違うようなので、少し待ってみて反映されてないようであれば、もう一度設定を見直してみてください。
面倒な検索作業を他の人に手伝ってもらえるサービス「Linch(リンク)」をリリースした
「助け合って検索する」をテーマにしたサービス「Linch(リンク)」のβ版をリリースしました!
面倒な検索作業を他の人に手伝ってもらえるサービス「Linch(リンク)」のβ版を改めてリリースしました!https://t.co/fm2m4B5c7U
— TaKO8Ki (@takoyaki3160) February 19, 2019
検索するのが億劫な時やあまり時間が取れない時に「Linch」に投稿すると、代わりに誰かが検索してくれるのを理想としたサービスです。#Linch #RT拡散お願いします
もし良かったら、拡散していただけたら嬉しいです!
リリースしたサービス
追記 2月22日
ご要望をいただいたので、Twitterアカウントでのログインを実装しました! もしよければ、Linchで情報収集してみてください!
サービスの概要
「Linch(リンク)」は、自分の知りたいことについて投稿すると、他のユーザーから関連するサイトのURLを教えてもらえるサービスです。 あるタスクに取り組んでいる時に、次のタスクで必要な情報を事前に手に入れておくなど、検索時間を短縮することに貢献できればと思っています。
トップページ
どこがリンクでどこがボタンとなっているかなど、できる限り見やすさを意識したデザインになるように心がけました。
投稿ページ
投稿するのは、知りたい情報に関するタイトル・タグ・概要のみです。少しでも画面遷移を少なくするためにポップアップで投稿できるようにしました。
記事表示ページ
ページ上部には、記事のタイトル・タグ・本文がページトップに表示されています。また、ページ下部には、記事に対して他のユーザーから投稿されたリンクの一覧を表示しています。
ユーザーページ
ユーザーが書いた記事に投稿されたリンクの合計いいね数・ストック数と記事の一覧が表示されています。
使用した技術
- Ruby・Ruby on Rails
- nokogiri (スクレイピングで有名なgem)
- acts-as-taggable-on (スペース区切りでタグを付けられるようになるgem)
- google-analytics-rails (google analyticsが簡単に導入できるgem)
- JavaScript・jQuery
画像を保存するストレージです。Herokuのアドオンとして利用できるのが非常やりやすかったです。
sitemapを保存するために利用しています。
Git・GitHub
- Postgresql
取り敢えず、Hobbyプランを利用しています。非常に簡単にWEBサービスを公開できるので、サービスの開発そのものに注力できました。
アイコン
- ボタンなどのアイコンは色々なフリー素材にお世話になりました。
また、ムームードメインでドメインを取得したのですが、ムームードメインで取得したドメインをHerokuで公開しているサービスにルートドメインとして設定する方法に関する情報があまり見つからなかったので、あとで記事を書いて追記したいと思います。
追記:記事を書きました。 Herokuで公開しているサービスに独自ドメインをサブドメインなしで設定する(ムームードメインの場合)
費用面
現在幸運にも大学生という身分なので、GitHub Student Developer Packを利用することができます。 学生の方は下記のリンクから受け取ることができます。 GitHub Student Developer Pack
GitHub Student Developer Packの特典の一つとして、下記のようにHerokuのHobbyプラン二年分($168分)が無料で使えるようです。
Heroku : One free Hobby Dyno for up to two years (valued at $84/year).
そのため、現在は、Herokuに対する費用は一切かかっていません。 また、Amazon S3に関しても無料枠内で収まると思われるので、一年間はドメインの取得料のみが費用になりそうです。
Linchの特徴
非ログインでもリンクの投稿といいねができる
twitterなどSNSに記事を投稿してURLを募集することを考えて、非ログインでもリンクを投稿したり、いいねができるようにしました。 ただし、リンクを募集するにはログインが必要です。
いいねが連打可能
好きなだけいいねが押せたほうが面白そうなので、いいねを連打することができるようにしました。 いいねボタン連打するだけでもいいので使ってみてください! いいねボタンを連打しにいく - Linch
とにかくシンプル
欲しい情報が素早く手に入る状態を目指したかったので、情報を「リンク(URL)」として集めるというシンプルな設計にしました。
リリースしてみての感想
やってみることの大切さ
ある程度の技術を身につけたら取り敢えず、何か作ってみることの大切さを改めて実感しました。例えリリースまで行うことができなくとも、コードと格闘して実装することを繰り返していると知らぬ間に技術は身についていくと感じました。
不安な気持ち
Linchの大部分を開発し終わった時に、あまりsearch engineとの差別化ができてないように思いましたが、完成させてみることが大切だと思ったので、一旦その考えは心の奥底にしまいました。 また、大学では、情報系の学科に通っているわけではないもあって、サービスのフィードバックなどを受け取る機会が非常に少なかったです。これからいろんな方にフィードバックをもらえる機会を増やしていきたいです。
デザインの難しさ
やはり、デザインは非常に難しいです。デザインに凝りすぎると沼にハマりそうだったので、諦めの気持ちも大切だと思いました。cssも勉強したいと思います。
最後に
プログラミングを始めてから八ヶ月という段階でついに自分が作りたいものを形にする段階まで来ることができました。 これからも触れていきたい技術がたくさんありますが、自分が習得したことを臆病にならずにアウトプットしていこうと思います。
現状、自分ひとりで投稿を続けている状態なので、一人目のユーザーお待ちしています! また、バグ・デザインの乱れがあれば、教えていただければありがたいです。
もしよろしければ、いいねボタンを押していただけたら嬉しいです!
ご覧いただきありがとうございました!
追記
①自動更新されるウィークリーいいねランキングに載せていただきました。 https://qiita.com/takeharu/items/bb154a4bc198fb102ff3#_reference-1eb95e9a3ff1e12b75d1
②多くの人にご覧いただけて非常に嬉しいです!もしよろしければ、何か投稿を残していただけれるとさらに嬉しいです!
③2/20 16:10頃からLinchを訪れてもエラーが表示されてしまっていましたが、16:25には復旧しました。
Railsでoauth access tokenなどを暗号化した
目的
方法
- gemなど、色々な暗号の方法がある。
- 結果的に今回は、Rails5.2から導入されたEncrypted Credentialsを利用することにした。
実際やってみる
以下のコマンドを叩く
$ EDITOR=vim bin/rails credentials:edit
EDITORの部分でエディターを指定できるらしいけど、環境変数:EDITORを設定しておかないといけないので、今回はvimで行う。
vimが開いて、下記のようになる。
# aws: # access_key_id: 123 # secret_access_key: 345 # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. secret_key_base: #######################
vimのコマンドをよく忘れるので、下記のURLを貼っておきます。 qiita.com
vimで編集したら、:wq入力して保存。 保存したら、
- config/credentials.yml.enc
- config/master.key
が生成される。
この時、master.keyにあるのは暗号化の鍵なので.gitignoreに追加されるようになってる。※
値の取り出し方
secret.yml
hoge: 123 fuga: fuga_id: 345
上記のようになっている場合は、下記のように値を取り出せる。
Rails.application.credentials.hoge # => "123" Rails.application.credentials.fuga[:fuga_id] # => 345
※何故かmaster.keyがレポジトリに表示されていた
今回、上記のように暗号化をしてみたが、なぜかmaster.keyがレポジトリに上がってしまっていた。 これでは、暗号化の意味がないので、自分で.gitignoreしないといけない。
そんな時は、下記のようにしてから、commitしてpushしたらファイルがGIthub上に表示されなくなる。
$ git rm -r --cached config/master.key
参考
Railsでbundle installしたらnokogiriでエラー出る現象
bundle installしたらnokogiriのインストール中にエラー出た
bundle installすると、途中で下記のようなエラーが出る。
Fetching nokogiri 1.10.1 Installing nokogiri 1.10.1 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
ググってみたら、色々出てきたけど、最終的に公式ページ見るのが一番良いみたい。
Macで、公式ページ通りの手順通りに進めていくと、下記のようになる。
gem update --system
xcode-select --install # Then agree to the terms, even if you have done this before!
gemが最新のバージョンかどうか確認して、
gem install nokogiri
これでもう一度bundle installしたらうまくいった!
Railsで複数の外部アプリケーションによるログイン機能を実装する。
外部アプリケーションのアカウントを使ったログイン機能を実装することがあったので、振り返りとしてまとめることにしました。
目的
Twitter・Githubなどのアカウントでログインできるような機能の実装を行う。
前提
devise gemによってログイン機能を実装していること。
実装方法
gemのインストール
下記を追記して、bundle installを実装する。
Gemfile
gem 'omniauth' gem 'omniauth-facebook' gem 'omniauth-github' gem 'omniauth-google-oauth2' gem 'omniauth-linkedin' gem 'omniauth-mixi' gem 'omniauth-twitter'
oauth申請
それぞれのアプリケーションでoauthの申請をしましょう!
「{外部アプリケーションの名前} oauth 申請」と検索したら大体分かると思います。
oauth申請でcallback用のURLが必要な場合は、とりあえず、
https://localhost:3000/user/auth/[provider]/callback
としましょう。
一例として、githubでは下記のリンクから申請できます。
この申請をすることで、AccessKeyとAccessSecretが得られます。
AccessKeyとAccessSecretをアプリ上に追記
下記のように、それぞれのアプリケーションで得られたAccessKeyとAccessSecretをomniauth.ymlに入れる。
config/omniauth.yml
production: &production facebook: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX github: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX google: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX hatena: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX linkedin: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX mixi: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX twitter: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX development: &development <<: *production facebook: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX github: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX mixi: key: xxxxxxxxxxx secret: XXXXXXXXXXXXXXXXXXXXXXXXX test: <<: *development
developmentとproductionで分かれているアプリケーションがあるのは、 申請の際にcallback用のURLを一緒に登録しなければならないために、開発環境と本番環境でそれぞれoauthの申請をしなければならないからです。
(開発環境では、「http://localhost:3000/」で本番環境では、「https://hoge.com/」みたいな感じ)
これらkeyやsecretは、本番環境では暗号化しなければなりません。 暗号化の方法については、下記を参考にすると分かりやすいと思います。
受け取る情報の設定
下記のようにします。
devise.rb
OAUTH_CONFIG = YAML.load_file("#{Rails.root}/config/omniauth.yml")[Rails.env].symbolize_keys! # https://github.com/mkdynamic/omniauth-facebook # https://developers.facebook.com/docs/concepts/login/ config.omniauth :facebook, OAUTH_CONFIG[:facebook]['key'], OAUTH_CONFIG[:facebook]['secret'], scope: 'email,publish_stream,user_birthday' # https://github.com/intridea/omniauth-github # http://developer.github.com/v3/oauth/ # http://developer.github.com/v3/oauth/#scopes config.omniauth :github, OAUTH_CONFIG[:github]['key'], OAUTH_CONFIG[:github]['secret'], scope: 'user,public_repo' # https://github.com/zquestz/omniauth-google-oauth2 # https://developers.google.com/accounts/docs/OAuth2 # https://developers.google.com/+/api/oauth config.omniauth :google_oauth2, OAUTH_CONFIG[:google]['key'], OAUTH_CONFIG[:google]['secret'], scope: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me https://www.google.com/m8/feeds', name: :google # https://github.com/mururu/omniauth-hatena # http://developer.hatena.ne.jp/ja/documents/auth/apis/oauth config.omniauth :hatena, OAUTH_CONFIG[:hatena]['key'], OAUTH_CONFIG[:hatena]['secret'] # https://github.com/skorks/omniauth-linkedin # https://developer.linkedin.com/documents/authentication # https://developer.linkedin.com/documents/profile-fields config.omniauth :linkedin, OAUTH_CONFIG[:linkedin]['key'], OAUTH_CONFIG[:linkedin]['secret'], scope: 'r_basicprofile r_emailaddress r_network', fields: [ "id", "first-name", "last-name", "formatted-name", "headline", "location", "industry", "summary", "specialties", "positions", "picture-url", "public-profile-url", # in r_basicprofile "email-address", # in r_emailaddress "connections" # in r_network ] # https://github.com/pivotal-sushi/omniauth-mixi # http://developer.mixi.co.jp/connect/mixi_graph_api/api_auth/ config.omniauth :mixi, OAUTH_CONFIG[:mixi]['key'], OAUTH_CONFIG[:mixi]['secret'] # https://github.com/arunagw/omniauth-twitter # https://dev.twitter.com/docs/api/1.1 config.omniauth :twitter, OAUTH_CONFIG[:twitter]['key'], OAUTH_CONFIG[:twitter]['secret']
それぞれのアプリケーションで受け取る情報が異なっています。
テーブル
① ターミナルで下記を実行して、SocialProfileテーブルを作成する
rails g model SocialProfile
② 作成したテーブルのカラムを設定する
①で作成した[作成した日時]_create_social_profiles.rbのchangeメソッドを下記のように編集する。
[作成した日時]_create_social_profiles.rb
def change create_table :social_profiles do |t| t.references :user, foreign_key: true t.string :provider t.string :uid t.string :name t.string :nickname t.string :email t.string :url t.string :image_url t.string :description t.text :other t.text :credentials t.text :raw_info t.timestamps end add_index :social_profiles, [:provider, :uid], unique: true end
その後、下記のコマンドを実行する。
rails db:migrate
少し上記のカラムについて説明します。
下記は大体どのアプリケーションでも受け取る情報となるので、必須のカラムです。
- provider
- uid
- description
- image_url
- url
それ以外のカラムは、自分がどの外部アプリケーション認証を導入するかによって少しずつ変化していきます。
どんなカラムを追加すればいいかについては、それぞれの外部アプリケーションアカウントを導入するためのgemのREADME.mdを読めば大体わかるようになっていると思います。 例えば、Twitterであれば、以下のURLのREADME.mdに記載されています。
モデル
下記のようにsocial_profile.rbに追記します。
social_profile.rb
class SocialProfile < ApplicationRecord belongs_to :user store :other validates_uniqueness_of :uid, scope: :provider scope :search_with_providers, ->(provider) { where(provider: provider) } def set_values(omniauth) return if provider.to_s != omniauth['provider'].to_s || uid != omniauth['uid'] credentials = omniauth['credentials'] info = omniauth['info'] self.access_token = credentials['token'] self.access_secret = credentials['secret'] self.credentials = credentials.to_json self.email = info['email'] self.name = info['name'] self.nickname = info['nickname'] self.description = info['description'].try(:truncate, 255) self.image_url = info['image'] case provider.to_s when 'hatena' self.url = "https://www.hatena.ne.jp/#{uid}/" when 'github' self.url = info['urls']['GitHub'] self.other[:blog] = info['urls']['Blog'] when 'google' self.nickname ||= info['email'].sub(/(.+)@gmail.com/, '\1') when 'linkedin' self.url = info['urls']['public_profile'] when 'mixi' self.url = info['urls']['profile'] when 'twitter' self.url = info['urls']['Twitter'] self.other[:location] = info['location'] self.other[:website] = info['urls']['Website'] end self.set_values_by_raw_info(omniauth['extra']['raw_info']) end def set_values_by_raw_info(raw_info) case provider.to_s when 'google' self.url = raw_info['link'] when 'twitter' self.other[:followers_count] = raw_info['followers_count'] self.other[:friends_count] = raw_info['friends_count'] self.other[:statuses_count] = raw_info['statuses_count'] end self.raw_info = raw_info.to_json self.save! end end
この部分では、それぞれの外部アプリケーションで処理を分けて値を代入しています。 自分が実装したい外部アプリケーション以外の処理の部分だけ追記しましょう。
次に、user.rbを下記のようにします。
user.rb
class User < ActiveRecord::Base devise :omniauthable has_many :social_profiles, dependent: :destroy def social_profile(provider) social_profiles.select{ |sp| sp.provider == provider.to_s }.first end end
ルーティング
routes.rbに下記のように追加します。 下記では、コントローラーがusersディレクトリ以下にある場合のルーティングを示しています。自分のディレクトリに変更しましょう。
routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks", :registrations => 'users/registrations' }
コントローラー
deviseでのログイン機能の導入を前提にしているので、現時点で、下記のコントローラーがある場合もあるかもしれません。
- confirmations_controller.rb
- passwords_controller.rb
- registrations_controller.rb
- sessions_controller.rb
- unlocks_controller.rb
- omniauth_callbacks_controller.rb
もし無い場合は、下記のコマンドで作成されます。
ディレクトリ名は好きなようにで入力しましょう。
rails g devise:controllers [ディレクトリ名]
先ほど作成したomniauth_callbacks_controller.rbに下記のように追記します。
omniauth_callbacks_controller.rb
def facebook; basic_action; end def github; basic_action; end def google; basic_action; end def hatena; basic_action; end def linkedin; basic_action; end def mixi; basic_action; end def hatena; basic_action; end private def basic_action @omniauth = request.env['omniauth.auth'] if @omniauth.present? @profile = SocialProfile.where(provider: @omniauth['provider'], uid: @omniauth['uid']).first unless @profile @profile = SocialProfile.where(provider: @omniauth['provider'], uid: @omniauth['uid']).new @profile.user = current_user || User.create!(username: @omniauth['name'], email: dammy_mail, password: dammy_password) @profile.save! end if current_user flash[:notice] = "外部アプリケーションとの連携が完了しました" if current_user == @profile.user flash[:alert] = "このアカウントは他のユーザーによって連携されています" if current_user != @profile.user else sign_in(:user, @profile.user) end @profile.set_values(@omniauth) end redirect_to user_path(current_user) end def dammy_mail dammy_mail = "hoge@example.com" return dammy_mail end def dammy_password dammy_password = "000000" return dammy_password end
dammy_mail、dammy_passwordとあるのは、deviseのログイン機能でemailとpasswordに対して存在のバリデーションを設けているからです。
参考
以上で終了です。もし、間違っているところなどがあれば教えていただけるとありがたいです!