Journey.

使用OAuthSwift完成微博OAuth2.0授权

昨天关于新浪的授权鼓捣了一天才弄好,所以写一个这个过程。主要用到的是OAuthSwift(一个适用于iOS/macOS等的OAuth库,支持1.0和2.0)
另外关于整个授权的过程,Practical Guide for using Sina Weibo’s API 也很有帮助。

  1. 新浪开发者,申请App,填写认证和App资料(略)
  2. 在project中导入OAuthSwift库(略)
  3. 授权 doOAuthWeibo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import OAuthSwift
import AppKit
class ViewController: OAuthViewController {
var oauthswift: OAuthSwift?
}
extension ViewController {
override func viewDidLoad() {
super.viewDidLoad()
doOAuthWeibo()
}
// MARK: Weibo
func doOAuthWeibo(){
// 注意这里使用的是OAuth2Swift,因为微博使用的也是OAuth2.0
let oauthswift = OAuth2Swift(
consumerKey: "XXXXXXX",
consumerSecret: "XXXXXXXXXXXXXXXXXXXXXXXX",
authorizeUrl: "https://api.weibo.com/oauth2/authorize",
accessTokenUrl: "https://api.weibo.com/oauth2/access_token",
responseType: "code"
)
let state = generateState(withLength: 20)
self.oauthswift = oauthswift
oauthswift.allowMissingStateCheck = true
oauthswift.authorizeURLHandler = OAuthSwiftOpenURLExternally.sharedInstance
// 这里的callback URL一定要与在微博APP页面填写的一致
let _ = oauthswift.authorize(withCallbackURL: URL(string: "http://your/callback/url")!,
scope: "full",
state: state,
success: { (credential, response, parameters) in
print("OAuth successful")
self.weibo(oauthswift, token: credential.oauthToken) // 发布一条微博
}) { (error) in
print(error.description)
}
}
// post a weibo for testing
func weibo(_ oauthswift: OAuth2Swift, token: String) {
let param = [
"format": "html",
"status": "Hello, world! \(arc4random())",
"access_token": token
]
let _ = oauthswift.client.post("https://api.weibo.com/2/statuses/update.json", parameters: param, success: { (OAuthSwiftResponse) in
print("posted")
}, failure: { (OAuthSwiftError) in
print("post failed")
print(OAuthSwiftError)
})
}
// generate random state
public func generateState(withLength len : Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let length = UInt32(letters.characters.count)
var randomString = ""
for _ in 0..<len {
let rand = arc4random_uniform(length)
let idx = letters.index(letters.startIndex, offsetBy: Int(rand))
let letter = letters.characters[idx]
randomString += String(letter)
}
return randomString
}
}
  1. 关于callback URL
    因为微博只接受http格式的URL,所以我在自己博客新建了一个页面作为callback URL(http://kelicheng.github.io/simple-sender/)
    在这个页面放一段代码重新定向到App中。
    1
    2
    3
    4
    <script type="text/javascript">
    var query = window.location.href.replace("http://your/callback/url", "YourAppName://oauth-callback/");
    window.location.assign(query)
    </script>

此外还要在project中设置URL Schemes:
Targets -> (YourAPP) -> Info -> URL Types -> Add -> URL Schemes = YourAppName

OAuthSwift的作者还给出了Ruby和PHP的代码示例,以及另一种使用内置浏览器授权的解决方案。详见:https://github.com/OAuthSwift/OAuthSwift/wiki/API-with-only-HTTP-scheme-into-callback-URL