iOS Moya实现OAuth请求的方法

0. 起源

开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

而作为第三方软件,为用户提供 OAuth 登录是更好的选择,可以有效打消用户对于个人账户密码泄露的顾虑,同时也能有效避免用户反复登录,进而增加用户的舒适度,提高用户粘性。

1. 环境

项目使用 MVVM 架构,引入了 Rx 全家桶,网络请求框架使用了 Moya,以及处理 Oauth 相关的库 OAuth2

2. OAuth2 部分

参阅 OAuth2 库的 README,完成 OAuth 的信息配置:

let oauth2 = OAuth2CodeGrant(settings: [
  "client_id": "my_swift_app",
  "client_secret": "C7447242",
  "authorize_uri": "https://github.com/login/oauth/authorize",
  "token_uri": "https://github.com/login/oauth/access_token",
  "redirect_uris": ["myapp://oauth/callback"],
  "scope": "user repo:status",
  "secret_in_body": true,
  "keychain": false,
] as OAuth2JSON)

同时因为 Moya 的底层网络请求实现是基于 Alamofire,因此我们可以参照 OAuth2 提供的说明文档 Alamofire 4 · p2/OAuth2 Wiki · GitHub完成相关配置,关键代码如下:

import Foundation
import OAuth2
import Alamofire

class OAuth2RetryHandler: RequestRetrier, RequestAdapter {

  let loader: OAuth2DataLoader

  init(oauth2: OAuth2) {
    loader = OAuth2DataLoader(oauth2: oauth2)
  }

  /// Intercept 401 and do an OAuth2 authorization.
  public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
    if let response = request.task?.response as? HTTPURLResponse, 401 == response.statusCode, let req = request.request {
      var dataRequest = OAuth2DataRequest(request: req, callback: { _ in })
      dataRequest.context = completion
      loader.enqueue(request: dataRequest)
      loader.attemptToAuthorize() { authParams, error in
        self.loader.dequeueAndApply() { req in
          if let comp = req.context as? RequestRetryCompletion {
            comp(nil != authParams, 0.0)
          }
        }
      }
    }
    else {
      completion(false, 0.0)  // not a 401, not our problem
    }
  }

  /// Sign the request with the access token.
  public func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
    guard nil != loader.oauth2.accessToken else {
      return urlRequest
    }
    return try urlRequest.signed(with: loader.oauth2)  // "try" added in 3.0.2
  }
}

3. Moya 部分

Moya 的 provider 在初始化时可以传入 SessionManager ,因此参照文档,可以先使用 OAuth2 生成一个特定的 SessionManager :

func getManager() -> SessionManager {

    let oauth2 = OAuth2CodeGrant(settings: [
      "client_id": "my_swift_app",
      "client_secret": "C7447242",
      "authorize_uri": "https://github.com/login/oauth/authorize",
      "token_uri": "https://github.com/login/oauth/access_token",
      "redirect_uris": ["myapp://oauth/callback"],
      "scope": "user repo:status",
      "secret_in_body": true,
      "keychain": false,
      ] as OAuth2JSON)

    let sessionManager = SessionManager()
    let oauthHandler = OAuth2Handler(oauth2: oauth2)
    sessionManager.adapter = oauthHandler
    sessionManager.retrier = oauthHandler
    return sessionManager
  }

进而生成带 OAuth 的 provider:

fileprivate lazy var provider: MoyaProvider = {
  return MoyaProvider<API>(manager: self.getManager(),
              plugins: [NetworkLoggerPlugin()])
}()

使用

使用生成的 provider 发送请求即可,此时 Moya 可自动处理 OAuth 认证信息。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS开发之路--微博OAuth授权_取得用户授权的accessToken

    最终效果图: OauthViewController.m // // OauthViewController.m // 20_帅哥no微博 // // Created by beyond on 14-8-5. // Copyright (c) 2014年 com.beyond. All rights reserved. // 授权控制器,仅运行一次,取得了当前用户的access_token和uid之后,存档,切换窗口的主控制器 #import "OauthViewController.h&quo

  • iOS Moya实现OAuth请求的方法

    0. 起源 开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 而作为第三方软件,为用户提供 OAuth 登录是更好的选择,可以有效打消用户对于个人账户密码泄露的顾虑,同时也能有效避免用户反复登录,进而增加用户的舒适度,提高用户粘性. 1. 环境 项目使用 MVVM 架构,引入了 Rx 全家桶,网络请求框架使用了 Moya,以及处理 Oauth 相关的库 OAuth2. 2. OAu

  • IOS开发 支持https请求以及ssl证书配置详解

    IOS开发 支持https请求以及ssl证书配置详解 前言: 众所周知,苹果有言,从2017年开始,将屏蔽http的资源,强推https 楼主正好近日将http转为https,给还没动手的朋友分享一二 一.证书准备 1.证书转换 在服务器人员,给你发送的crt证书后,进到证书路径,执行下面语句 // openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der 这样你就可以得到cer类型的证书了.双击,导入电脑. 2.证书放入工程 1.可以直接把转换好

  • IOS多线程编程NSThread的使用方法

    IOS多线程编程NSThread的使用方法 NSThread是多线程的一种,有两种方法创建子线程 (1)优点:NSThread 比GCD.NSOperation都轻量级 (2)缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 第一种是隐藏创建,有以下几种方式: (1)多用于串行:- (id)performSelector:(SEL)aSelector withObject:(id)object; (2)后台执行,多用于并行:- (void)performSele

  • JavaScript利用fetch实现异步请求的方法实例

    前言 相信大家应该都有所了解,在这个AJAX时代,如果想进行 API 等网络请求都是通过 XMLHttpRequest 或者封装后的框架进行网络请求. 现在产生的 fetch 框架简直就是为了提供更加强大.高效的网络请求而生,虽然在目前会有一点浏览器兼容的问题,但是当我们进行一些异步请求时,都可以使用 fetch 进行完美的网络请求.下面话不多说,来一起看看详细的介绍吧. 先来看看各个浏览器对fetch的原生支持情况,可以看到支持性并不是很高,safari在10.1 之后才支持,ios更是10.

  • 怎么防止ios系统被抓包?防止ios系统被抓包的方法

    怎样防止ios系统被抓包? 我们知道ios系统 是可以通过 [fiddler][6] ,[charles][6]等抓包工具来获取APP发送的API,以及传送的参数等,那么上线之后怎么防止之中情况呢? 我们都大概了解抓包的操作,需要手机与抓包工具在同一网段,然后设置代理,之后就可以进行你要抓包的操作了,那么接下来要做的事情 就相对相对简单了,我们可以检查自己的网络是否处于代理网络之下,如果这个时候处于代理网络下就拒绝发送任何请求. 那么如何检测是否有代理 以下提供几个检测代理的方法 first:

  • iOS开发TableView网络请求及展示预加载实现示例

    目录 引言 传统的上拉加载更多 滑动过程中预加载 方法1(最简单.高效和最推荐): 方法2(自己计算实现,不推荐了): 下面是具体实现细节(此细节是针对上述方法2的) 总结 引言 2022.02.11更新:新增了最简单.高效和最推荐的方法. 2020.05.25更新:对总结进行了详细的补充. 传统的上拉加载更多 在iOS的开发过程中,如果用列表展示数据,此时一般的逻辑为上拉加载更多数据,配合MJRefresh就是在滑动到最底部时,触发加载更多的网络请求. 滑动过程中预加载 如果希望体验好一点,那

  • 详解AngularJS中$http缓存以及处理多个$http请求的方法

    $http 是 AngularJS 中的一个核心服务,用于读取远程服务器的数据.在AngularJS的实际项目中,经常需要处理多个$http请求,每个$http请求返回一个promise,我们可以把多个promise放到$q.all()方法接受的一个数组实参中去. 1.处理多个$http请求 angular.module('app',[]) .controller('AppCtrl', function AppCtrl(myService){ var app = this; myService.

  • IOS获取各种文件目录路径的方法

    iphone沙箱模型有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory()), 手动保存的文件在documents文件里 Nsuserdefaults保存的文件在tmp文件夹里 1.Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它应该定期备份的信息. 2.AppName.app 目录:这是应用程序的程序包目录,包

  • 浅谈iOS中三种生成随机数方法

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(time(0)); int i = random() % 5; //第三种 int i = arc4random() % 5 ; 注: ① rand()和random()实际并不是一个真正的伪随机数发生器,在使用之前需要先初始化随机种子,否则每次生成的随机数一样. ② arc4random() 是一个

  • 基于CORS实现WebApi Ajax 跨域请求解决方法

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特别各种APP万花齐放的今天,API的跨域请求是不能避免的. 在默认情况下,为了防止CSRF跨站的伪造攻击(或者是 javascript的同源策略(Same-Origin Policy)),一个网页从另外一个域获取数据时就会收到限制.有一些方法可以突破这个限制,那就是大家熟知的JSONP, 当然这只是众多

随机推荐