質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

OpenID

OpenIDは、様々なWebサイトで 1つのID情報のみで認証が可能にするサービスです。

Q&A

解決済

1回答

1410閲覧

sns認証にて(主にlineで)id_tokenからemail取得ができない

yaharu

総合スコア1

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

OpenID

OpenIDは、様々なWebサイトで 1つのID情報のみで認証が可能にするサービスです。

0グッド

0クリップ

投稿2021/11/17 08:11

###質問
railsでline認証を行っています。そこで、id_tokenからemailも取得したいのですが取得できません。以下のコードでどこが間違っているのでしょうか。また、以下のようにputsで出力してもherokuのログに出力がされません。そこもできれば教えていただけると助かります。
###コード
model/user.rb

require 'uri' require 'net/http' class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:facebook, :line] has_many :posts has_many :likes has_many :post_likes, through: :likes, source: :post mount_uploader :user_image, ImageUploader validates :username, {uniqueness: true, presence: true, length: {maximum: 15}} def self.find_for_oauth(auth, code) id_token_payload_email = User.get_access_token(code) unless id_token_payload_email #クライアントアプリにemail取得をユーザが許可していない場合 return id_token_payload_email = User.dummy_email(auth) end user = User.where(uid: auth.uid, provider: auth.provider).first if user == nil user = User.new( uid: auth.uid, provider: auth.provider, email: id_token_payload_email, username: auth.info.name, password: Devise.friendly_token[0, 20]#開発者にも分からないようにランダムなパスワードが作られる。 ) elsif user.provider == nil #userアカウント持っていて途中からsns認証使う場合 user = User.new( uid: auth.uid, provider: auth.provider ) end user.skip_confirmation! user.save user end def self.get_access_token(code) uri = URI.parse("https://api.line.me/oauth2/v2.1/token")#アクセストークン取得。この際に、同じハッシュにid_tokenも含まれる request = Net::HTTP::Post.new(uri) request.content_type = "application/x-www-form-urlencoded" request.set_form_data( "client_id" => ENV["LINE_APP_ID"], "client_secret" => ENV["LINE_APP_SECRET"], "code" => "#{code}", "grant_type" => "authorization_code", "redirect_uri" => "https://spot-share-site.herokuapp.com//users/sign_up", ) req_options = { use_ssl: uri.scheme == "https", } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end id_token = JSON.parse(response.body)["id_token"] puts id_token id_token_payload = User.get_id_token(id_token) return id_token_payload[:email] end def self.get_id_token(id_token) uri = URI.parse("https://api.line.me/oauth2/v2.1/verify") #id_tokenの中身を取得(ペイロード部) request = Net::HTTP::Post.new(uri) request.content_type = "application/x-www-form-urlencoded" request.set_form_data( client_id: ENV["LINE_APP_ID"], id_token: id_token ) req_options = { use_ssl: uri.scheme == "https", } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end puts response return response end def self.dummy_email(auth) return "#{auth.uid}-#{auth.provider}@example.com" end end

controller/users/omniauth_callbacks_controller

# frozen_string_literal: true class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController # You should configure your model like this: # devise :omniauthable, omniauth_providers: [:twitter] # You should also create an action method in this controller like this: # def twitter # end # More info at: # https://github.com/heartcombo/devise#omniauth # GET|POST /resource/auth/twitter # def passthru # super # end # GET|POST /users/auth/twitter/callback # def failure # super # end # protected # The path used when OmniAuth fails # def after_omniauth_failure_path_for(scope) # super(scope) # end def facebook callback_from :facebook end def line callback_from :line end private def callback_from(provider) provider = provider.to_s code = params[:code] @user = User.find_for_oauth(request.env['omniauth.auth'], code) if @user.persisted? flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize) sign_in_and_redirect @user, event: :authentication #sign_in(:user, @user) else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url end def failure redirect_to root_path end end end

色々調べると、initializer/omniauthにてomniauthをオーバライドしてopenidconnectを実装している人が多かったです。しかし、上記のコードでemailが取得できない理由が分かりません。どうか宜しくお願い致します。

###試したこと
ログを見てみると、emailにはdummy_emailで生成されたメールアドレスが入っていたのでid_tokenのペイロード部にemailがなかったかそもそもアクセストークン取得やペイロード部取得のhttp通信がうまくいっていないか。そこで、よく見ると#Net::HTTPBadRequest:0x0000562b9349bd48と返ってきてました。

###参考
https://developers.line.biz/en/reference/line-login/#refresh-access-token
###環境
Ruby version 2.7.3

Rails version 6.1.4.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こちらの記事は誤って投稿されたものなのでクローズさせて頂きます。

投稿2021/11/17 09:21

yaharu

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問