三方登录- iOS Twitter登录

news2024/9/19 10:50:29

背景

在现代移动应用中,集成第三方登录已经成为一种常见的需求,它不仅能提高用户体验,还能减少用户注册的阻力。我们选择了 Twitter 作为示例,但类似的步骤和逻辑也适用于其他第三方登录服务。希望这篇博客能为你提供清晰的指导,并帮助你在应用中成功实现第三方登录。

Twitter登录与其它三方登录不同,比如Facebook官方提供了完整的SDK可以直接使用,业务场景中有遇到的话难免会有点不知所措,下面就介绍一下Twitter登录的实现方案。

实现方案一

虽然Twitter没有提供官方的SDK但是也在开发者网站上也推荐了两个github的库。

https://developer.x.com/en/docs/twitter-api/tools-and-libraries/v2

我们以TwitterAPIKit为例:

1.点击连接下载TwitterAPIKit到本地。
2.打开自己的项目点击file->Add Package Dependenceis将刚刚下载的Package添加到项目。

添加后项目结构如下:

3.Info.plist文件增加scheme

允许回调到你的APP

允许打开其它APP

4.代码实现

声明一些必要属性

class ViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {
   
    /// 替换成你自己的consumerKey
    let consumerKey = "consumerKey"
    /// 替换成你自己的consumerSecret
    let consumerSecret = "consumerSecret"
    /// callbackURL
    var callbackURL:String!
    /// scheme
    var scheme:String!
    
    var client:TwitterAPIClient!

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

consumerKey和consumerSecret是在开发平台创建自己应用后可以获取到的两个数据。

callbackURL和scheme需要自己进行拼接

        callbackURL = "twitterkit-\(consumerKey)://"
        scheme = "twitterkit-\(consumerKey)"

点击登录按钮后创建TwitterAPIClient的实例client,并发起post请求获取用户token和secret

@objc func loginAction() {
        callbackURL = "twitterkit-\(consumerKey)://"
        scheme = "twitterkit-\(consumerKey)"
        client = TwitterAPIClient(.oauth10a(.init(consumerKey: consumerKey, consumerSecret: consumerSecret, oauthToken: nil, oauthTokenSecret: nil)))
        client.auth.oauth10a.postOAuthRequestToken(.init(oauthCallback: callbackURL)).responseObject {[weak self] response in
            guard let self = self else { return }
            do {
                let success = try response.result.get()
                let url = self.client.auth.oauth10a.makeOAuthAuthorizeURL(.init(oauthToken: success.oauthToken))!
                let session = ASWebAuthenticationSession(url: url, callbackURLScheme: scheme) { url, error in
                    // url is "twitter-api-kit-ios-sample://?oauth_token=<string>&oauth_verifier=<string>"
                    guard let url = url else {
                        if let error = error {
                            print(error)
                        }
                        return
                    }
                    print("URL:", url)

                    let component = URLComponents(url: url, resolvingAgainstBaseURL: false)
                    guard let oauthToken = component?.queryItems?.first(where: { $0.name == "oauth_token"} )?.value,
                          let oauthVerifier = component?.queryItems?.first(where: { $0.name == "oauth_verifier"})?.value else {
                        print("Invalid URL")
                        return
                    }
                    self.client.auth.oauth10a.postOAuthAccessToken(.init(oauthToken: oauthToken, oauthVerifier: oauthVerifier))
                        .responseObject { response in
                            do {
                                let token = try response.result.get()
                                let oauthToken = token.oauthToken
                                let oauthTokenSecret = token.oauthTokenSecret
                                print("result : \(oauthToken), \(oauthTokenSecret)")
                            } catch {
                               print(error)
                            }
                        }
                }
                session.presentationContextProvider = self
                session.prefersEphemeralWebBrowserSession = true
                session.start()

            } catch {
                print(error)
            }
        }
    }
    
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return view.window!
    }

将获取到的token和screte传递给服务端,完成Twitter登录。

但是这里面有个问题,由于我们使用ASWebAuthenticationSession,它主要用于处理 OAuth 和 OpenID Connect 等 web 基于身份验证的流程。ASWebAuthenticationSession 让应用程序可以安全地打开一个浏览器界面(使用 Safari 浏览器)来完成认证过程,并在认证完成后将结果返回给应用程序。

所以即使安装了TwitterAPP也不能调起TwitterAPP,整个认证过程都是在自己的APP内进行。

实现方案二

再介绍一种更简单的实现方式,不需要借助任何三方代码,直接使用ASWebAuthenticationSession或者UIApplication.shared.open的方式打开认证页面。

为了可以调起Twitter我们这里使用UIApplication.shared.open的方式。

info.plist文件的设置与上面相同,这里就不过多介绍了。

代码实现

我们为它单独创建了一个单利

class CSTwitterHelper: NSObject {
    
    static let shared = CSTwitterHelper()
    ....
}

同样需要使用Consumer_Key和Consumer_Secret。

  let Twitter_Consumer_Key = "pxvBpjJMk4OwxA1rB7R3OnSEN"
    let Twitter_Consumer_Secret = "EQzLWzeIBqZzOr1WN6g4V6aH0WUNiDwFx6aQkGtG20E2xLwCaD"
    
    var successCompletion: ((_ accessToken:String,_ accessTokenSecret:String) -> Void)?
    var failure: ((_ error:Error) -> Void)?

点击登录时,直接使用UIApplication.shared.open方式打开拼接的url

    /// twitter登录
    /// - Parameters:
    ///  - successCompletion: 成功回调
    ///  - fairlure: 失败回调
    func twitterLogin(successCompletion: @escaping (_ accessToken:String,_ accessTokenSecret:String) -> Void,fairlure: @escaping (_ error:Error) -> Void) {
        let url = "twitterauth://authorize?consumer_key=\(Twitter_Consumer_Key)&consumer_secret=\(Twitter_Consumer_Secret)&oauth_callback=twitterkit-\(Twitter_Consumer_Key)"
        UIApplication.shared.open(URL(string: url)!, options: [:]) { success in
            if !success {
                let error = NSError(domain: "twitter", code: 101, userInfo: [NSLocalizedDescriptionKey:"Cannot open twitter app"])
                fairlure(error)
            }
        }
        self.successCompletion = successCompletion
        self.failure = fairlure
    }

在AppDelegate中设置回调,如果你保留了SceneDelegate也需要设置回调。

 func application(
        _ app: UIApplication,
        open url: URL,
        options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {
        // twitter
        if url.scheme == "twitterkit-\(CSTwitterHelper.shared.Twitter_Consumer_Key)" {
            return CSTwitterHelper.shared.twitterApplication(app, open: url, options: options)
        }
    }

在回调中获取我们需要的token和secret传递给服务端。

    /// twitter登录回调
    /// - Parameters:
    /// - app: UIApplication
    /// - url: URL
    /// - options: [UIApplication.OpenURLOptionsKey : Any]
    /// - Returns: Bool
    func twitterApplication(_ app: UIApplication,open url: URL,options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let isCanceled = (url.host == nil)
        if isCanceled {
            // 用户取消
            let error = NSError(domain: "twitter", code: 100, userInfo: [NSLocalizedDescriptionKey:"User canceled"])
            self.failure?(error)
            return false
        }
        let params = url.queryParams
        let secret = params["secret"]
        let token = params["token"]
        let userName = params["username"]
        if let token = token,let secret = secret {
            self.successCompletion?(token,secret)
        } else {
            let error = NSError(domain: "twitter", code: 102, userInfo: [NSLocalizedDescriptionKey:"params error"])
            self.failure?(error)
        }
        return true
    }

其中url.queryParams是为URL添加了一个扩展方法,用来获取参数。

extension URL {
    
    /// 获取参数
    var queryParams: [String : String] {
        guard let host = self.host else { return [:] }
        return host.split(separator: "&").reduce(into: [:]) { (result, parameter) in
            let keyValue = parameter.split(separator: "=")
            result[String(keyValue[0])] = String(keyValue[1])
        }
    }
}

结语

对客户端来说Twitter登录,只需要获取到token和secret就算完成了,任何一种方法只要能从Twitter获取到这两个数据就算登录成功了。

感谢你的阅读,如果你有任何问题或需要进一步的帮助,请随时留言交流。祝你开发顺利,项目成功!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1686217.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring】spring入门程序

案例要求&#xff1a;创建一个 Studentservice 类&#xff0c;其中需要使用 studentDao 接口的保存方法&#xff0c;来存储一个Student 类的对象&#xff0c;StudentDao 接口有两个不同的实现类&#xff0c;通过 Spring 的方式&#xff0c;为 Student类创建对象并为属性赋值&am…

2024电工杯B题食谱评价与优化模型思路代码论文分析

2024年电工杯数学建模竞赛B题论文和代码已完成&#xff0c;代码为B题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模型的建立和求解、问题3模型的建立和求解&#xff09;、模型…

vmware - 主机向虚拟机拷贝文件的临时方法

文章目录 vmware - 主机向虚拟机拷贝文件的临时方法概述笔记确认主机/虚拟机之间网络是通的在虚拟机中新建一个文件夹(e.g. c:\test), 将这个文件夹设为共享文件夹。查看虚拟机中的当前用户(远程登录要用)远程登录END vmware - 主机向虚拟机拷贝文件的临时方法 概述 程序打包…

go 微服务框架kratos错误处理的使用方法及原理探究

通过go语言原生http中响应错误的实现方法&#xff0c;逐步了解和使用微服务框架 kratos 的错误处理方式&#xff0c;以及探究其实现原理。 一、go原生http响应错误信息的处理方法 处理方法&#xff1a; ①定义返回错误信息的结构体 ErrorResponse // 定义http返回错误信息的…

vscode 插件开发指南

1安装nodejs、vscode 2安装插件脚手架 npm install -g yo generator-code 3使用命令创建插件项目 yo code 4在vscode中打开项目 5运行调试&#xff0c;按F5键 6在新打开的窗口中按shiftctrlp 然后执行命令 7配置右键菜单命令 遇到问题&#xff1a; 1.package.json中vsc…

【ELK日志收集过程】

文章目录 为什么要使用ELK收集日志ELK具体应用场景ELK日志收集的流程 为什么要使用ELK收集日志 使用 ELK&#xff08;Elasticsearch, Logstash, Kibana&#xff09;进行日志收集和分析有多种原因。ELK 堆栈提供了强大、灵活且可扩展的工具集&#xff0c;能够满足现代 IT 系统对…

B端概念稿,贼靓!像概念车一样未必落地,但是潮流引领。

概念稿在UI设计中往往难以落地&#xff0c; 主要有以下几个原因&#xff1a; 抽象性&#xff1a;概念稿通常是设计师在初始阶段为了表达和传达设计理念而创建的&#xff0c;它们往往比较抽象和概念化。这使得概念稿在实际落地时需要进一步细化和具体化&#xff0c;以便开发人员…

ChatGPT类大模型应用入门了解与使用

一 前言 ChatGPT大众热情逐渐褪去&#xff0c;但在后台技术人的探索还处于热火朝天状态。如果我们生活的世界是一杯清水&#xff0c; 那类似ChatGPT的语言大模型技术的横空出世就如滴入水杯的一滴墨汁&#xff0c;第一滴很显眼&#xff0c;但实际上是后续墨汁慢慢扩散渗透才是…

[数据集][目标检测]森林火灾检测数据集VOC+YOLO格式362张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;362 标注数量(xml文件个数)&#xff1a;362 标注数量(txt文件个数)&#xff1a;362 标注类别…

生成模型 | 从 VAE 到 Diffusion Model (上)

文章目录 一&#xff0c;GAN(对抗式生成网络&#xff09;二&#xff0c;Auto-Encoder(AE) 和 Denoising Auto-Encoder (DAE)三&#xff0c;VAE四&#xff0c;VQ-VAE (Vector Quantized Variational Autoencoder)VQ-VAE 2小总结&#xff1a; 五&#xff0c;DALL-E &#xff08;O…

Google speech command 数据集获取

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Java学习【接口的使用实例,浅克隆与深克隆】

Java学习【接口的使用实例&#xff0c;浅拷贝与深拷贝】 Comparable接口String类型比较多个对象的比较 Comparator接口Cloneable接口浅拷贝深拷贝 Comparable接口 当我们想要比较两个基本数据类型的大小时直接用 > , < , 就可以了&#xff0c;那么如果是自定义的类要根…

为什么我们应该放弃定义敏感数据?

个人数据与人以及其他个人数据深深地交织在一起&#xff0c;它就像一幅巨大的挂毯&#xff0c;而这些线是无法轻易拆开的。尝试定义敏感数据就像徒劳地试图从挂毯中找出不同的线头一样&#xff0c;线头与其他线头交织在一起&#xff0c;一旦开始拆线&#xff0c;整个挂毯就会散…

IP地址概述和配置

一.IP地址的概述 在计算机网络中&#xff0c;连接的网络设备和计算机都有唯一的地址&#xff0c;以此作为该计算机在internet中的唯一标识。 二.IP地址的定义 IP地址&#xff08;internet protocol Address&#xff0c;网络协议地址&#xff09;是用于表示网络节点的逻辑地址…

黄石首家Pearson VUE国际认证考试中心落户湖北理工学院

Pearson VUE 作为 Pearson 集团的专门从事计算机化考试服务的公司&#xff0c;到目前为止&#xff0c;已在全世界165 个国家授权了 4400 多个考试中心以及超过 230 家 PVUE 自有考试中心&#xff0c;其中在中国的有三百多个授权考点和 4 个自有考试中心。Pearson VUE 以其技术和…

虚拟列表 vue-virtual-scroller 的使用

npm 详情&#xff1a;vue-virtual-scroller - npm (npmjs.com) 这里我使用的是RecycleScroller。 App.vue <template><RecycleScrollerclass"scroller":items"items":item-size"54"v-slot"{ item }"><list-item :it…

『光谷云智慧大屏』数字智慧型 案例赏析

设计背景 随着数字化转型的不断深入&#xff0c;智慧大屏在云数据处理中心扮演着越来越重要的角色。大屏采用先进技术&#xff0c;构建了一个直观且互动的实时数据监控系统。它不仅提高了数据处理的效率&#xff0c;还为数据中心的智能化管理和运营提供了强有力的支持&#xf…

智慧工地势在必行,可以减少管理的无序状态,效率倍增。

智慧工地的建设对于提高工地管理效率和减少无序状态具有重要意义。智慧工地通过引入先进的信息技术和智能化设备&#xff0c;可以实现以下方面的优势&#xff1a; 1. 实时监测和管理&#xff1a; 智慧工地可以通过传感器、监控摄像头等设备对施工现场的各种参数和情况进行实时…

RGMII接口及时序详解

文章目录 一、RGMII接口介绍二、MAC和PHY1.关系2.MAC和PHY的交互3.MAC为什么要配置PHY4.如何配置&#xff08;1&#xff09;原理&#xff08;2&#xff09;PHY地址的确定&#xff08;3&#xff09;寄存器地址及配置数据 三、88E1111中PHY的时序1.接收端时序&#xff08;1&#…

Windows安全应急--应急排查的一些方法

前言&#xff1a; 非法BC植入网站安全应急&#xff0c; 在安全应急中&#xff0c; 总会需要大大小小的问题&#xff0c; 就像成长一样。 检测工具尽量使用轻量级的。。 本次演示环境 Windows Server 2008 问题排查步骤&#xff1a; 先判断服务器有没有被Rootkit 查看登录…