iOS实现OAuth2.0中刷新access token并重新请求数据操作
一、简要概述
OAuth2.0是OAuth协议的下一版本,时常用于移动客户端的开发,是一种比较安全的机制。在OAuth 2.0中,server将发行一个短有效期的access token和长生命期的refresh token。这将允许客户端无需用户再次操作而获取一个新的access token,并且也限制了access token的有效期。即当sever发送的access token过期之后,客户端会调用方法,将access token和refresh token发送给服务端,服务端将会返回新的access token和refresh token。
二、应用场景
用户登录后,服务端会发行一个有效时间的access token,同时也会发行一个长生命期的refresh token。用户在进行其他网络请求时,会把access token加入请求体中(并不需要加入refresh token)。如果在请求过程中,access token过期,返回相应的状态码。这时就回调用一个回调方法,在回调方法体中将原来的access token和refresh token发送给服务端,获取新的access token和refresh token。然后把新的access token加入刚才的请求体中,重新加载网络请求。
限定access token的有效时间,只是为了提高安全性。access token过期后重新获取并重新加载请求这一操作,用户是察觉不到的。这种机制在微信、QQ、微博等客户端中尤为常见。
三、实例代码
(1)此类继承了AFNetworking中的AFHTTPSessionManager类,并重写了里面的方法。
NetWorkCallBack.h:
#import <Foundation/Foundation.h>
#import <AFNetworking.h>
@interface NetWorkCallBack : AFHTTPSessionManager @end
NetWorkCallBack.m:
#import "NetWorkCallBack.h"
#import <SSKeychain.h>
@implementation NetWorkCallBack - (NSURLSessionDataTask *)dataTaskWithRequest:(NSMutableURLRequest *)urlRequest completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))originalCompletionHandler{ //create a completion block that wraps the original
void (^authFailBlock)(NSURLResponse *response, id responseObject, NSError *error) = ^(NSURLResponse *response, id responseObject, NSError *error)
{
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
if([httpResponse statusCode] == ){ //如果access token过期,返回错误,调用此block
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, ), ^{ //调用refreshAccesstoken方法,刷新access token。
[self refreshAccessToken:^(AFHTTPRequestOperation *operation) {
//存取新的access token,此处我使用了KeyChain存取
NSDictionary *headerInfo = operation.response.allHeaderFields;
NSString *newAccessToken = [headerInfo objectForKey:@"access-token"];
NSString *newRefreshToken = [headerInfo objectForKey:@"refresh-token"];
[SSKeychain deletePasswordForService:@"<key>" account:@"access-token"];
[SSKeychain deletePasswordForService:@"<key>" account:@"refresh-token"];
[SSKeychain setPassword:newAccessToken forService:@"<key>" account:@"access-token"];
[SSKeychain setPassword:newRefreshToken forService:@"<key>" account:@"refresh-token"]; //将新的access token加入到原来的请求体中,重新发送请求。
[urlRequest setValue:newAccessToken forHTTPHeaderField:@"access-token"]; NSURLSessionDataTask *originalTask = [super dataTaskWithRequest:urlRequest completionHandler:originalCompletionHandler];
[originalTask resume];
}];
});
}else{
NSLog(@"no auth error");
originalCompletionHandler(response, responseObject, error);
}
}; NSURLSessionDataTask *stask = [super dataTaskWithRequest:urlRequest completionHandler:authFailBlock]; return stask; }; /*
*获取新的token的方法。如何获取可以自定义,我这里用了AFNetWorking的AFHTTPRequestOperation类
*/
-(void)refreshAccessToken:(void(^)(AFHTTPRequestOperation *responseObject))refresh{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:@"<yourURL>"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //将原来的access token和refresh token发送给服务器,以获取新的token
NSString *accessToken = [SSKeychain passwordForService:@"<key>" account:@"access-token"];
NSString *refreshToken = [SSKeychain passwordForService:@"<key>" account:@"refresh-token"]; [request setValue:accessToken forHTTPHeaderField:@"access-token"];
[request setValue:refreshToken forHTTPHeaderField:@"refresh-token"]; //执行网络方法
AFHTTPRequestOperation *httpRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation * operation, id responseObject) {
refresh(operation);
} failure:^(AFHTTPRequestOperation * operation, NSError * error) {
refresh(operation);
}];
[httpRequestOperation start];
}
@end
iOS实现OAuth2.0中刷新access token并重新请求数据操作的更多相关文章
- 工作笔记—新浪微博Oauth2.0授权 获取Access Token (java)
java发送新浪微博,一下博客从注册到发布第一条微博很详细 利用java语言在eclipse下实现在新浪微博开发平台发微博:http://blog.csdn.net/michellehsiao/art ...
- 新浪微博Oauth2.0授权 获取Access Token
新浪微博开放平台提供了丰富的API接口,利用这些接口,开发者能够开发出独具特色的微博应用.但是,大部分接口都需要用户授权给应用,应用利用授权得到的Access Token来调用相应的接口来获取内容. ...
- ASP.NET OAuth:解决refresh token无法刷新access token的问题
最近同事用iOS App调用Open API时遇到一个问题:在access token过期后,用refresh token刷新access token时,服务器响应"invalid_gran ...
- OAuth 白话简明教程 4.刷新 Access Token
转自:http://www.cftea.com/c/2016/11/6705.asp OAuth 白话简明教程 1.简述 OAuth 白话简明教程 2.授权码模式(Authorization Code ...
- 在Asp.Net Core 3.0中如何使用 Newtonsoft.Json 库序列化数据
在.Net Core 3.0中 内置了一套Json序列化/反序列化方案,默认可以不再依赖,不再支持 Newtonsoft.Json. 但是.NET Core 3.0 System.Text.Jso ...
- Python实现接口测试中的常见四种Post请求数据
前情: 在日常的接口测试工作中,模拟接口请求通常有两种方法, 利用工具来模拟,比如fiddler,postman,poster,soapUI等 利用代码来模拟,使用到一些网络模块,比如HttpClie ...
- iOS新浪微博OAuth2.0认证代码
#import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...
- Thinkphp中controller控制器根据curl函数请求数据
public function member(){ $url="http://aitequn.tjnit.com/UserAction_findAllUser"; $ch =cur ...
- OAuth2.0 微博登陆网站功能的实现(一)获取用户授权及令牌 Access Token
在登陆一些网站的时候,可以选择登陆方式为第三方登陆,例如微博登陆,以爱奇艺为例,进入首页,点击 ”登陆“,会弹出登录框: 除了本站登陆外,还可以选择其他第三方登陆,比如微博登陆.QQ 登陆.微信登陆等 ...
随机推荐
- 多项式求和 AC 杭电
多项式求和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 转:php连接oracle设定字符集,避免乱码
原文来自于:http://muyu.iteye.com/blog/399884 数据库用oracle,当php连接oracle的时候,最好指定字符集. 查PHP手册,oci_connect的第四个参数 ...
- hdu Co-prime
题意:求出在一个区间[A,B]内与N互质的个数 . 思路: 先求出n的质因子,然后求出与N的质因子不互质的个数然后总个数减去就是.用位运算二进制表示那个因子用到过,实现容斥原理.在1到n之间是c倍数的 ...
- 如何使用mysql
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...
- POJ 3281 牛双选问题
题目大意:有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有N头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物 ...
- 在 Windows 下远程桌面连接 Linux - XManager 篇
XManager是一个简单易用的高性能的运行在Windows平台上的X-Server软件,而Gnome和KDE就是X-Client,Linux下的X-Server则为Xorg.它能把远端Unix/Li ...
- 关于TFS2012无法发送警报邮件的问题
前几天把公司的TFS从2010升级到2012,整个过程经历了3个小时,过程比较顺利.升级完成后眼馋各种新功能,感叹知识真是待到用时方恨少呐,只得一个一个去摸索了.其中有一个“警报”的功能让我印象深刻( ...
- Linux 下最为人熟知的解压缩工具
很多时候,通过互联网发送或接收大文件和图片是一件令人头疼的事.压缩及解压缩工具正好可以应对这个问题.下面让我们快速浏览一些可以使得我们的工作更加轻松的开源工具. Tar Tar 由 ‘Tape arc ...
- DateGradeView分页绑定
<form method="post" id="nform" runat="server"> < ...
- redis: 6379端口下set值时出现 CLUSTERDOWN The cluster is down
1.使用./redis-trib.rb check 192.168.242.134:6379检查出现图中的错误 2.在redis安装目录的bin下执行下列命令去cluster meet 另一个端口为7 ...