Yahoo! ID連携

iOS

STEP2: サンプルコードを確認して実装する

  • Authorization Codeフロー
  • Implicitフロー

iOS(Authorization Codeフロー)

iOSのAuthorization Codeフローのサンプルコードの説明をします。



ライブラリーをプロジェクトに追加する

Yahoo! ID連携 iOS SDKを任意の場所にダウンロードして解凍してください。解凍後、YConnectSDK.xcodeprojをアプリケーションのプロジェクトに追加してください。詳細な手順を下記に示します。

  1. XCodeでアプリケーションのプロジェクトを開いてください。
  2. XCodeのメニューから"File" > "Add Files To <プロジェクト名>"を選択してください。
  3. 解凍したYahoo! ID連携 iOS SDK内のYConnectSDK.xcodeprojを選択し、"Add"してください。


プロジェクトの設定

はじめにYahoo! ID連携 iOS SDKを利用するためにプロジェクトの設定を行います。

まずはビルドターゲットの"Build Phase"を開き、"Link Binary With Libraries"の"+"ボタンを押してください。

ダイアログが表示されるので、WorkspaceからlibYConnectSDK.aを選択し、"Add"してください。

次にYahoo! ID連携 iOS SDK内のヘッダファイルをimportするために設定を行います。

ビルドターゲットの"Build Settings"を開き、設定項目中の"Header Search Paths"にYahoo! ID連携 iOS SDKのパスを追加します。

最後にコールバックURLを設定します。

ビルドターゲットの"Info"を開き、"URL Types"を展開してください。

"+"ボタンを押すと入力フォームが表示されるので、"identifier"に一意な値を、

"URL schemes"にはこのschemeはアプリケーションID登録時に発行されるカスタムURIスキーム「yj-xxxxx」を指定してください。

"identifier"に指定する値は"Bundle identifier"と同じ値が推奨されています。

また、カスタムURIスキームはアプリケーションの管理から変更可能です。



Authorizationエンドポイントにリクエストして同意画面を表示する

YConnectExplicitクラスにはAuthorization Codeフローで必要なメソッドがすべて実装されています。
YConnectExplicitクラスを使ってアプリケーションのWebView内に同意画面を表示させます。

なお、サンプルコードはStoryboardを使用しています。

YConnectExplicitクラス

メソッド 説明
- (YConnectExplicit *)getInstance シングルトンパターンのインスタンスを取得する。
- (YConnectExplicit *)initWithClientId:(NSString *)clientId redirectUri:(NSString *)redirectUri state:(NSString *)state responseType:(NSString *)responseType display:(NSString *)display prompt:(NSString *)prompt scope:(NSString *)scope nonce:(NSString *)nonce 各パラメーターを設定する。
- (NSURL *)generateAuthorizationUri 同意画面を取得する。

OIDCDisplayクラス

定数フィールド値 説明
+ (NSString *) DEFAULT パソコン版のテンプレートを表示するための定数です。
+ (NSString *) SMART_PHONE スマートフォンブラウザー版のテンプレートを表示するための定数です。
+ (NSString *) IN_APP スマートフォンアプリケーション版のテンプレートを表示するための定数です。

OIDCPromptクラス

定数フィールド値 説明
+ (NSString *) DEFAULT ユーザーの認証、認可のための定数です。
+ (NSString *) NONE 同意画面非表示のための定数です。(必須の場合はエラーが返却されます)
+ (NSString *) CONSENT ユーザーの再認可のための定数です。
+ (NSString *) LOGIN ユーザーの再認証のための定数です。

OIDCScopeクラス

定数フィールド値 説明
+ (NSString *) OPENID ユーザー識別子を取得するための定数です。
+ (NSString *) PROFILE 姓名・生年・性別を取得するための定数です。
+ (NSString *) EMAIL メールアドレスと確認済みフラグを取得するための定数です。
+ (NSString *) ADDRESS ユーザー登録住所情報を取得するための定数です。
StartViewController.h
...
@interface StartViewController : UIViewController

- (IBAction)loginAction:(id)sender;
@property (nonatomic, retain) NSURL *url;

...
StartViewController.m
...
// アプリケーションID
static NSString * const CLIENT_ID = @"あなたのアプリケーションID";
// コールバックURL
// (アプリケーションID発行時に登録したURI)
static NSString * const REDIRECT_URI = @"yj-xxxxx://cb";

...

//ログイン用のアクションを作成
- (IBAction)loginAction:(id)sender
{
    // YConnectインスタンス取得
    YConnectExplicit *yconnect = [YConnectExplicit getInstance];

    // 各パラメーター初期化
    // リクエストとコールバック間の検証用のランダムな文字列を指定してください
    NSString *state = @"44GC44GC54Sh5oOF";
    NSString *responseType = [OAuth2ResponseType CODE_IDTOKEN];
    // リプレイアタック対策のランダムな文字列を指定してください
    NSString *nonce = @"U0FNTCBpcyBEZWFkLg==";
    NSString *display = [OIDCDisplay SMART_PHONE];
    NSString *prompt = [OIDCPrompt EMPTY];
    NSString *scope = [NSString stringWithFormat:@"%@ %@ %@ %@", [OIDCScope OPENID], [OIDCScope PROFILE], [OIDCScope EMAIL], [OIDCScope ADDRESS]];

    ...

    // 各パラメーターを設定
    yconnect = [yconnect initWithClientId:CLIENT_ID redirectUri:REDIRECT_URI state:state responseType:responseType display:display prompt:prompt scope:scope nonce:nonce];
    // AuthorizationエンドポイントのURLを生成
    NSURL *url = [yconnect generateAuthorizationUri];
    self.url = url;

    //Segueを使ってWebViewを持ったViewControllerに遷移
    [self performSegueWithIdentifier:@"StartToWeb" sender:self];
}
    
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ...
    if ( [[segue identifier] isEqualToString:@"StartToWeb"] ) {
        WebViewController *webViewController = [segue destinationViewController];
        //WebViewにURLを渡す
        webViewController.url = self.url;
    }
    ...
}

...

実際の開発の際にはstate、nonceは固定の文字列ではなく独自の仕様でランダムな文字列を生成してデータベースなどに保存してください。stateはAuthorizationエンドポイントからのコールバックURL受取時に、nonceはIDトークンを復号時の検証に必要です。

各パラメーター値の詳細についてはAuthorizationエンドポイントを参照してください。

WebViewに生成したURIを設定して読み込みます。

WebViewController.m
...
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    CGRect rect = [[UIScreen mainScreen] applicationFrame];
    UIWebView *webView = [[UIWebView alloc] initWithFrame:rect];
    webView.scalesPageToFit = YES;
    [self.view addSubview:webView];
    
    NSURLRequest *req = [NSURLRequest requestWithURL:self.url];
    
    [webView loadRequest:req];
    webView.delegate = self;
}
...


コールバックURLを受け取り、認可コードを抽出する

同意後に返されるコールバックURLをAppDelegateで受け取り、認可コードなどを抽出します。

YConnectExplicitクラス

メソッド 説明
- (void)parseAuthorizationResponse:(NSURL *)uri customUriScheme:(NSString *)customUriScheme state:(NSString *)state コールバックURLのクエリパラメータに付加されたパラメーターを抽出する。
- (NSString *)getAuthorizationCode 認可コードを取得する。
AppDelegate.m
..
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL*)url {
    
    //コールバックURLに指定したURLだった場合、最初のViewControllerから結果を表示するViewControllerに遷移する
    if ([url.scheme isEqualToString:@"yj-xxxxx"]) {
        StartViewController *viewController = [self.window.rootViewController.childViewControllers objectAtIndex:0];
        viewController.url = url;
        [viewController performSegueWithIdentifier:@"StartToResult" sender:viewController];
        return YES;
    }
    return NO;
}
StartViewController.m
...
    
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ...
    if ( [[segue identifier] isEqualToString:@"StartToResult"] ) {
        ResultViewController *resultViewController = [segue destinationViewController];
        //コールバックURLをViewControllerに渡す
        resultViewController.url = self.url;
    }
    ...
}

...
ResultViewController.h
..
@interface ResultViewController : UIViewController

@property (nonatomic, retain) NSURL *url;

...
ResultViewController.m
..

// コールバックURLから各パラメーターを抽出
YConnectExplicit *yconnect = [YConnectExplicit getInstance];
[yconnect parseAuthorizationResponse:self.url customUriScheme:@"yj-xxxxx://" state:yconnect.requestClient.state];
// 認可コードを取得
NSString *code = [yconnect getAuthorizationCode];

...


Tokenエンドポイントにリクエストしてアクセストークンを取得する

取得した認可コードを用いてアクセストークンを取得します。

YConnectExplicitクラス

メソッド 説明
- (void)requestToken:(NSString *)code redirectUri:(NSString *)redirectUri clientId:(NSString *)clientId Tokenエンドポイントにリクエストする。
- (NSString *)getAccessToken アクセストークンを取得する。
- (long)getAccessTokenExpiration アクセストークンの有効期限を取得する。
- (NSString *)getRefreshToken リフレッシュトークンを取得する。
- (NSString *)getIdToken IDトークンを取得する。
ResultViewController.m
...
// Tokenエンドポイントにリクエスト
[yconnect requestToken:code redirectUri:REDIRECT_URI clientId:CLIENT_ID];
// アクセストークン、リフレッシュトークン、IDトークンを取得
NSString *accessTokenString = [yconnect getAccessToken];
long expiration = [yconnect getAccessTokenExpiration];
NSString *refreshToken = [yconnect getRefreshToken];
NSString *idTokenString = [yconnect getIdToken];
...


CheckTokenエンドポイントにリクエストしてユーザー識別子を取得する

オプションでレスポンスタイプにIDトークンを指定した場合、IDトークンの暗号化された文字列が返されます。
この文字列をCheckTokenエンドポイントで復号し、ユーザー識別子やIDトークンの発行元などの情報を取得します。

YConnectExplicitクラス

メソッド 説明
- (void)requestCheckIdToken:(NSString *)idToken nonce:(NSString *)nonce clientId:(NSString *)clientId CheckTokenエンドポイントにリクエストする。
- (IdTokenObject *) getIdTokenObject 復号されたIDトークンをオブジェクトとして取得する。
ResultViewController.m
...
// CheckTokenエンドポイントにリクエスト
[yconnect requestCheckIdToken:idTokenString nonce:yconnect.nonce clientId:CLIENT_ID];
// 復号されたIDトークン情報を取得
IdTokenObject *idTokenObject = [yconnect getIdTokenObject];
...

復号されたIDトークンはオブジェクトとして返されます。各パラメーターはIDトークンオブジェクトのプロパティーに保持されているので、必要に応じて取り出して利用してください。



UserInfo APIにリクエストしてユーザー識別子を取得する

アクセストークンを用いてユーザー識別子などを取得します。

YConnectExplicitクラス

メソッド 説明
- (void)requestUserInfo:(NSString *)accessTokenString UserInfo APIにリクエストする。
- (id)getUserInfoObject UserInfoオブジェクトを取得する。
ResultViewController.m
...
// UserInfo APIにリクエスト
[yconnect requestUserInfo:accessTokenString];
// UserInfo情報を取得
UserInfoObject *userInfoObject = [yconnect getUserInfoObject];
...

userInfoObjectはオブジェクトとして返されます。各パラメーターはUserInfoオブジェクトのプロパティーに保持されているので、必要に応じて取り出して利用してください。



アクセストークンを更新する

リフレッシュトークンをつかって有効期限切れのアクセストークンを更新します。

YConnectExplicitクラス

メソッド 説明
- (void)refreshAccessToken:(NSString *)refreshToken clientId:(NSString *)clientId アクセストークンを更新する。
ResultViewController.m
...
if(/* エラーレスポンスが"Invalid_Token"であるかチェック */) {
...
    // Tokenエンドポイントにリクエストしてアクセストークンを更新する
    [yconnect refreshAccessToken:refreshToken clientId:CLIENT_ID];
    accessTokenString = [yconnect getAccessToken];
    expiration = [yconnect getAccessTokenExpiration];
...
}
...


アクセストークンなどの保存について

アクセストークン、IDトークン、UserInfo情報の保存は、悪意のある外部アプリケーションから盗みとられないように注意が必要です。
取得したトークンやユーザー情報を保存する場合には、適宜暗号化や難読化し外部から読み取られないようにしてください。



Yahoo!知恵袋で調べる