Swift_微信第三方登录

一、接入微信第三方登录准备工作。

移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。

1. 在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程

注意:

1.审核需要提供一个28*28和108*108的图标
2.审核需要提供Bundle ID
3.审核需要一点时间,我之前一天就审核通过了
2. 下载iOS微信SDK

下载最新的SDK 地址: 点击打开链接

Swift_微信第三方登录_第1张图片
Paste_Image.png

3. 将SDK放到工程目录中
Swift_微信第三方登录_第2张图片
Paste_Image.png
4. 补充导入一些依赖框架:Target - Build Phases - Link Binary With Libraries
Swift_微信第三方登录_第3张图片
Paste_Image.png
5. 添加URL Types:Target - Info - URL Types
Swift_微信第三方登录_第4张图片
Paste_Image.png
6. 添加iOS9 URL Schemes

**注意: 当程序出现以下错误,说明没有针对iOS9 增加白名单。在info.plist文件中加入 LSApplicationQueriesSchemes **

-canOpenURL: failed for URL: "weixin://app/wx9**********dfd30/" - error: "This app is not allowed to query for scheme weixin"
Swift_微信第三方登录_第5张图片
Paste_Image.png
7. iOS9中新增App Transport Security(简称ATS)特性, 主要使到原来请求的时候用到的HTTP,都转向TLS1.2协议进行传输。这也意味着所有的HTTP协议都强制使用了HTTPS协议进行传输。需要在Info.plist新增App Transport Security Settings用于控制ATS的配置:
NSAppTransportSecurity
 
       NSAllowsArbitraryLoads
       

如果我们在iOS9下直接进行HTTP请求是会收到如下错误提示,需要在Info.plist新增App Transport Security Settings

**App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.**
Swift_微信第三方登录_第6张图片
Paste_Image.png
8. 现在编译应该没有问题
二、代码部分
1. 第一步:在桥接文件中引入"WXApi.h"头文件,然后在中AppDelegate.m写入如下代码:
import UIKit

@UIApplicationMain
// 在Appdelegate里面添加微信代理
class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
       //向微信注册应用
       // @param1 微信开发者ID
       // @param2 应用附加信息,长度不超过1024字节
      WXApi.registerApp("wxed8b3e67969559b5", withDescription: "wechat")
        return true
    }
    
    // 这个方法是用于从微信返回第三方App 处理微信通过URL启动App时传递的数据
    // @param url 微信启动第三方应用时传递过来的URL
    // @param delegate WXApiDelegate对象,用来接收微信触发的消息。
    func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool {
        if url.scheme == "wxed8b3e67969559b5" {
            WXApi.handleOpenURL(url, delegate: self)
        }
        return true
    }

    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        if url.scheme == "wxed8b3e67969559b5" {
            WXApi.handleOpenURL(url, delegate: self)
        }
        return true
    }

    func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
        Tools.logPrint("openURL:\(url.absoluteString)")
        if url.scheme == "wxed8b3e67969559b5" {
            return WXApi.handleOpenURL(url, delegate: self)
        }
        return true
    }
}
2. 第二步:请求CODE

开发者需要配合使用微信开放平台提供的SDK进行授权登录请求接入。正确接入SDK后并拥有相关授权域(scope,什么是授权域?)权限后,开发者移动应用会在终端本地拉起微信应用进行授权登录,微信用户确认后微信将拉起开发者移动应用,并带上授权临时票据(code)。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        
        if WXApi.isWXAppInstalled() {
            print("weixin ready")
        } else {
            // 把微信登录的按钮隐藏掉
        }
    }

    // 请求CODE
    @IBAction func wechatLoginClick(sender: UIButton) {
        // 如果在这里判断是否安装了微信,会报-canOpenURL: failed for URL: "weixin://app/wx5efead4057f98bc0/" - error: "This app is not allowed to query for scheme weixin"错误
            let req = SendAuthReq()
            req.scope = "snsapi_userinfo"
            req.state = "App"
        //第三方向微信终端发送一个SendAuthReq消息结构
            if !WXApi.sendReq(req) {
                print("weixin sendreq failed")
       }
    }
}

执行完上面那一步后,如果客户端安装了微信,那么就会向微信请求相应的授权,图如下:

Swift_微信第三方登录_第7张图片
Paste_Image.png

返回说明
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。

Swift_微信第三方登录_第8张图片
Paste_Image.png

3. 第三步:通过code获取access_token
获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&gr
ant_type=authorization_code
Swift_微信第三方登录_第9张图片
Paste_Image.png
// 授权后回调
// AppDelegate.m
    func onReq(req: BaseReq!) {
        //onReq是微信终端向第三方程序发起请求,要求第三方程序响应。第三方程序响应完后必须调用sendRsp返回。在调用sendRsp返回时,会切回到微信终端程序界面。
        print(req.type)
    }
    
    func onResp(resp: BaseResp!) {
        //如果第三方程序向微信发送了sendReq的请求,那么onResp会被回调。sendReq请求调用后,会切到微信终端程序界面。
        if resp.isKindOfClass(SendAuthResp) {
            let authResp = resp as! SendAuthResp
            print("ErrCode : \(authResp.errCode)") // 0
            print("EodeStr : \(authResp.errStr)") // nil
            print("Code : \(authResp.code)") // 0017Avci0BJ0Rj1hIqai0jEsci07AvcI
            print("State : \(authResp.state)") //  State : App
            print("Lang : \(authResp.lang)") // nil
            print("Country : \(authResp.country)") // nil
            if authResp.errCode == 0 {
                let code = authResp.code
                let AFN = AFHTTPSessionManager()
                let params = ["appid": WX_APPID, "secret": WX_APPSECRET_TEST, "code": code, "grant_type": "authorization_code"]
                AFN.GET("https://api.weixin.qq.com/sns/oauth2/access_token", parameters: params, success: { (_, response) in
                    let accessToken = response!["access_token"] as! String
                    let refreshToken = response!["refresh_token"] as! String
                    let openID = response!["openid"] as! String
                    // 本地持久化,以便access_token的使用、刷新或者持续
                    if (accessToken.isEmpty == false && openID.isEmpty == false) {
                        NSUserDefaults.standardUserDefaults().setObject(accessToken, forKey: "access_token")
                        NSUserDefaults.standardUserDefaults().setObject(refreshToken, forKey: "refresh_token")
                        NSUserDefaults.standardUserDefaults().setObject(openID, forKey: "openid")
                        NSUserDefaults.standardUserDefaults().synchronize() // 命令直接同步到文件里,来避免数据的丢失
                    }
                    self.wechatLoginByRequestForUserInfo()
                    }, failure: { (_, error) in
                        print(error) 
                })
            }
        }
    }
Swift_微信第三方登录_第10张图片
Paste_Image.png
 // 获取用户个人信息(UnionID机制)
    func wechatLoginByRequestForUserInfo() {
        let accessToken = NSUserDefaults.standardUserDefaults().objectForKey("access_token")
        let openID = NSUserDefaults.standardUserDefaults().objectForKey("openid")
        // 获取用户信息
        let params = ["access_token": accessToken! as! String, "openid": openID! as! String] as Dictionary
        let AFN = AFHTTPSessionManager()
        AFN.GET("https://api.weixin.qq.com/sns/userinfo", parameters: params, progress: nil, success: { (_, response) in
            // 这里可以实现公司的要求,比如我司是微信登录成功后,通过segue跳转到主界面
            print(response)
            }, failure: { (_, error) in
              print(error)
        })
    }

你可能感兴趣的:(Swift_微信第三方登录)