Swift: GitHubのOAuthログインをiOSアプリからやってみた
iOS アプリから GitHub のアカウントで OAuth ログインするというのをやってみた。環境は Xcode 6 beta 4 と Swift。
参考にしたサイトはこちら。
» iOSアプリでGithubにOAuthする – yaakaito.org
それから公式ドキュメント。
最初に GitHub の Applications にてアプリケーション登録をして Client ID と Client Secret を取得。Authorization callback URL にはカスタムURLスキームを設定する必要がある。
ちなみにカスタムURLスキームのスキーム部分にピリオドが入っているとエラーになるので、 com.fkoji.someapp:// のような Bundle ID を元にしたURLスキームは使えない。someapp:// のような形式にしておくこと。

↑ Authorization callback URL の設定例。
次に OAuth ログインの実装。Twitter や Facebook と違って iOS 標準の SDK がないので まずは Safari ないしは UIWebView でログイン画面を開いてログインしてもらい、callback URL でアプリへ戻ってくるという流れになる。
let clientId = "your client id"
let url = NSString(
format: "https://github.com/login/oauth/authorize?client_id=%@",
clientId
)
// Safari が開く場合
UIApplication.sharedApplication().openURL(NSURL.URLWithString(url))
GitHub にログインしアプリケーションの連携を許可すると、指定したカスタムURLスキームに「?code=hogehoge」がついて戻ってくる。カスタムURLスキームは UIApplicationDelegate の application:openURL:sourceApplication:annotation: 内で解析。以下 AppDelegate.swift から抜粋。
func application(application: UIApplication!, openURL url: NSURL!, sourceApplication: String!, annotation: AnyObject!) -> Bool {
// callback URL に someapp://oauth/github と指定した場合、
// someapp://oauth/github?code=hogehoge のようなURLで戻ってくる
if url.scheme == "someapp" {
if url.host == "oauth" && url.lastPathComponent == "github" {
let kv = url.query.componentsSeparatedByString("=")
if kv[0] != "code" {
return false
}
let code = kv[1]
// サインイン (独自のクラスで定義)
let github = MyGitHubLogin()
github.getAccessToken(code)
return true
}
return false
}
return true
}
サインイン部分は独自のクラスに実装してみた。書き方は色々。ここでは AFNetworking を使ってアクセストークンの取得をおこなっている。
class MyGitHubLogin {
var code: String!
var clientId: String!
var clientSecret: String!
var accessToken: String!
init() {
// 上記の宣言時に let でセットしててもよい
self.clientId = "your client id"
self.clientSecret = "your client secret"
}
func getAccessToken(code: String!) {
self.code = code
let manager: AFHTTPRequestOperationManager = AFHTTPRequestOperationManager()
// GitHub の OAuth で JSON フォーマットのレスポンスを受け取るには Accept ヘッダーが必要
let requestSerializer = AFHTTPRequestSerializer()
requestSerializer.setValue("application/json", forHTTPHeaderField: "Accept")
manager.requestSerializer = requestSerializer
manager.POST(
"https://github.com/login/oauth/access_token",
parameters: [
"client_id": self.clientId,
"client_secret": self.clientSecret,
"code": self.code
],
success: { (operation, responseObject) in
if let response = responseObject as NSDictionary! {
self.accessToken = response["access_token"] as String!
// あとはお好みで…
}
},
failure: { (operation, error) in
// エラー時のアラート処理などはここに
}
)
}
}
アクセストークンが取得できれば、さらにそれを元に「https://api.github.com/user?access_token=…」をリクエストすることでプロフィール情報を取得できる。今回は取得したアクセストークンをサーバーサイドに投げてそっちでログイン処理をおこなう必要があったのでここでは割愛。
(修正履歴: 2014-08-15) MyGitHubLogin の login を getAccessToken に変更
コメントを残す