LoginSignup
10
9

More than 5 years have passed since last update.

MobileSDKを使わずにSalesforceにアクセスするiPhoneアプリを作る【認証編】

Posted at

Mobile SDKを使うとSalesforceにアクセスするモバイルアプリケーションが簡単に作れそうですが、単一の組織にログインするのが前提なため要件に合わず、今回はMobile SDKを使わずに作ってみましたので基本事項をまとめておきます(XcodeでのiPhoneアプリ開発の知識があるの前提です)。

Salesforceの認証(OAuth2.0)については、こちらをまず読んでおくと分かりやすいです。
https://wiki.developerforce.com/page/JP:Digging_Deeper_into_OAuth_2.0_at_Salesforce.com

接続アプリケーションの登録

開発用のSalesforce組織にログインし、「設定>アプリケーション」から接続アプリケーションを登録します。
ここで発行される「コンシューマ鍵」(=client_id)が認証の実装に必要です。
接続アプリケーション

StoryboardでUIの大枠を作る

まずは簡単に、認証してユーザ情報を表示するだけのアプリを作ります。
新規プロジェクトで、Master-Detail Applicationをひな形に、

  • Master ViewにはSign In用のボタン代わりのセルと、取得したユーザ情報を表示する用のセルをstatic cellとして置きました。
  • Detail Viewには認証のページを表示する為のUIWebViewを置きました。

Storyboard

OAuthでの認証

UIWebViewの初期表示として、認証画面に飛ばします。
クライアントアプリケーション用の認証方式、User-Agent Flowを使うため、response_type=tokenを指定します。

SEDetailViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];

    // OAuthの認証画面を初期表示(User-Agent Flow)
    NSString *authorizeURL = @"https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id=3MVG9I1kFE5Iul2Cbahhzus9WVFyGSQGrQ3gTYeMzkJGbA_43hAg0fb57FTxZkWASpInGI4lSg3gpzlL4WErb&redirect_uri=test%3A%2F%2Fcallback&display=touch";
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:authorizeURL]];

    _webview.delegate = self;
    [_webview loadRequest:req];
}

認証が終わった時のtest://callbackの処理をhookし、パラメータで返ってくる認証情報をバラします。
取得したaccess_tokenを使用して、idサービスでユーザの情報を取得します。

SEDetailViewController.m
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *absoluteURL = request.URL.absoluteString;

    // callback先以外の場合は通常のページ遷移
    if ([absoluteURL rangeOfString:@"test://callback"].location == NSNotFound) return YES;

    // #以降のパラメータをバラす
    NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:@"(\\w+)=([^&]+)" options:0 error:nil];
    NSArray *matches = [re matchesInString:absoluteURL options:0 range:NSMakeRange(0, absoluteURL.length)];
    NSMutableDictionary *authInfo = @{}.mutableCopy;

    for (NSTextCheckingResult *r in matches) {
        NSString *k = [absoluteURL substringWithRange:[r rangeAtIndex:1]];
        NSString *v = [absoluteURL substringWithRange:[r rangeAtIndex:2]];
        authInfo[k] = [v stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
    }

    // User-Agent Flowなのでaccess_tokenが直接返ってくる
    NSString *accessToken = authInfo[@"access_token"];

    // 取得したaccess_tokenを使ってidサービスに接続。ユーザ情報を取得する

    // access_tokenをAuthorizationヘッダへ
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.HTTPAdditionalHeaders = @{@"Authorization": [NSString stringWithFormat:@"Bearer %@", accessToken]};
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

    // idサービスのURLは'id'パラメータで返ってくる
    NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:authInfo[@"id"]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        // 取得したユーザ情報をMain Viewに渡して画面戻る
        NSDictionary *idInfo = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // メインスレッドで実行
            [self performSegueWithIdentifier:@"oauthSuccess" sender:@{@"authInfo":authInfo, @"idInfo":idInfo}];
        }];
    }];
    [task resume];

    return NO;
}

ソースコード全体はこちら

動かしてみるとこんな感じです(YouTube)

エラー処理等は特に入れてない基本部分のみですが、これでaccess_tokenを取得し、APIの呼び出しができました。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9