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

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

新規登録して質問してみよう
ただいま回答率
85.49%
OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

1859閲覧

iOSアプリでの、OAuthSwiftを用いたSpotify OAuth2.0認証でcallback処理が成功しません

canalun

総合スコア0

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/12/30 10:45

編集2020/12/30 12:58

はじめまして。
SwiftもTeratailも使い始めて日が浅く、分かる方からしたらくだらない質問かとは思いますが、お時間のあるどなたかがお答えくださることを願っております。よろしくお願いいたします。

前提・実現したいこと

Xcode12.3でiOS向けのSpotifyプレイリスト自動生成アプリを作っています。
ユーザーからプレイリスト作成権限を得るために、Safariと連携したOAuth2.0認証(PKCEは不使用)を実装しようとしています。その際に、OAuthSwiftの最新版(2.1.2)を使っています。
このOAuth認証が動きません。OAuth認証を正常に動作させたく質問しました。

発生している問題・エラーメッセージ

Safariと連携してのOAuth2.0認証(PKCEは不使用)がうまく動きません。
具体的には、後に掲載しているソースコードで実機ビルド(iPhone8, iOS14.3)をしたときに以下のように動作しています。
1.ボタン(clickButton)を押すと、Safari画面が表示され、そこではfacebook, apple, googleによるログインもしくはユーザー名とパスワードの直接入力によるログインのためのボタンが用意されている。
イメージ説明
また、この時点でXcode側のデバッガーには下記のメッセージが出ている。

success3 <OAuthSwift.SafariURLHandler: 0x283fc8500> success1 success2 Safari presented

2.いずれのログイン方法も、ボタン(「Facebookで続ける」ボタン等)を押してもうまくいかない。
具体的には下記のようになる。

  • appleで続けるボタン→iPhone上でappleIDと連携した指紋認証が行われ、Spotifyにログインはされるものの、Safariの画面が白くなり停止
  • それ以外のボタン  →何の反応も起きず、画面も上に掲載したままに留まる

なお、いずれの場合もXcodeのデバッガーに新規情報は入らない。

[追記]
ログインボタンを押した際の上記の反応は、実機上でのものでしたが、
エミュレーターでビルドしたところ、「Facebookで続ける」ボタンではユーザー名とパスワードを入れた後、下記の画面で終わってしまいました。
イメージ説明

該当のソースコード

ソースコードは下記のとおりです。ネット上のOAuthSwiftの様々な実装例を参考にしており、類似点があることをご容赦下さい。
consumerKeyおよびconsumerSecretは一旦非表示とさせていただきますが、こちらは記入ミスがないことを既に確かめております。

Swift

1import UIKit 2import OAuthSwift 3 4struct Const { 5 static let consumerKey = "XX" 6 static let consumerSecret = "XX" 7} 8 9class ViewController: UIViewController { 10 11 var oauthswift: OAuthSwift? 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 } 16 17 18 @IBAction func clickButton(_ sender: UIButton) { 19 doOAuthSpotify() 20 } 21 22 /// OAuth2ログイン処理 23 func doOAuthSpotify(){ 24 25 let oauthswift = OAuth2Swift( 26 consumerKey: Const.consumerKey, 27 consumerSecret: Const.consumerSecret, 28 authorizeUrl: "https://accounts.spotify.com/authorize", 29 accessTokenUrl: "https://accounts.spotify.com/api/token", 30 responseType: "code" 31 ) 32 self.oauthswift = oauthswift 33 oauthswift.authorizeURLHandler = getURLHandler() 34 35 print("success1") //for debug 36 let state = generateState(withLength: 20) 37 print("success2") //for debug 38 39 // コールバック処理 40 oauthswift.authorize(withCallbackURL: URL(string: "PlaylistMaker://")!, scope: "playlist-modify-private", state: state) 41 {result in 42 print("callback") //for debug 43 switch result { 44 case .success(let (credential, response, parameters)): 45 print(credential.oauthToken) 46 self.showAlert(credential: credential) 47 print("success") 48 case .failure(let error): 49 print(error.localizedDescription) 50 print("failure") 51 } 52 } 53 } 54 55 /// ログイン画面起動に必要な処理 56 /// 57 /// - Returns: OAuthSwiftURLHandlerType 58 func getURLHandler() -> OAuthSwiftURLHandlerType { 59 if #available(iOS 11.0, *) { 60 let handler = SafariURLHandler(viewController: self, oauthSwift: self.oauthswift!) 61 handler.presentCompletion = { 62 print("Safari presented") 63 } 64 handler.dismissCompletion = { 65 print("Safari dismissed") 66 } 67 print("success3") //for debug 68 print(handler) //for debug 69 return handler 70 } 71 print("OS has to be updated as later than iOS 10.0") 72 return OAuthSwiftOpenURLExternally.sharedInstance 73 } 74 75 /// アラート表示 76 /// 77 /// - Parameter credential: OAuthSwiftCredential 78 func showAlert(credential: OAuthSwiftCredential) { 79 var message = "oauth_token:(credential.oauthToken)" 80 if !credential.oauthTokenSecret.isEmpty { 81 message += "\n\noauth_token_secret:(credential.oauthTokenSecret)" 82 } 83 let alert = UIAlertController(title: "ログイン", 84 message: message, 85 preferredStyle: UIAlertController.Style.alert) 86 alert.addAction(UIAlertAction(title: "OK", 87 style: UIAlertAction.Style.default, handler: nil)) 88 self.present(alert, animated: true, completion: nil) 89 } 90} 91

試したこと

redirect URIの問題かと思い、Spotify側で設定しているものと違った文字列をあえてcallbackで設定した際はInvalid URIエラーが実機で確認できました。現在は正しいURIを使用しており、そこに問題はないようです。
素人考えではありますが、callback処理がなぜ始まらないのかという点に尽きるのかと考えております。しかしそれが様々に調べてみるもののわからず質問させていただきました。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問