您的位置:首页 > 移动开发 > IOS开发

iOS新浪微博客户端开发(2)——OAuth授权

2015-04-13 11:16 176 查看
转载自:http://blog.csdn.net/chy305chy/article/details/43202991

一、什么是OAuth?

1、OAuth是一种协议,OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准

2、任何服务提供商只要想把自己的用户资源共享出去,都可以实现自身的OAuth认证服务。比如腾讯可以实现自己的OAuth认证服务,把用户的QQ数据共享出去

3、同时,任何第三方都可以使用OAuth认证服务,第三方若想访问用户资源,就必须遵守服务提供商实现的OAuth协议
总结一下,OAuth可以用来控制用户资源的访问权限。比如我们想访问用户的新浪微博数据,就必须通过新浪实现的OAuth认证。

二、OAuth授权的步骤

1、首先获取未授权的RequestToken:



代码如下:

[objc] view
plaincopy

// 1. 获取未授权的RequestToken,加载登陆界面  

    NSString *urlStr = [kAuthorizeURL stringByAppendingFormat:@"?display=mobile&client_id=%@&redirect_uri=%@", kAppKey, kRedirectURI];  

    NSURL *url = [NSURL URLWithString:urlStr];  

    NSURLRequest *request = [NSURLRequest requestWithURL:url];  

    [_loginWebView loadRequest:request];  

2、获取用户授权的RequestToken



代码如下:

[objc] view
plaincopy

#pragma mark 实现代理方法,拦截webView请求,Sent before a web view begins loading a frame.  

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType  

{  

    // 1. 获得全路径  

    NSString *urlStr = request.URL.absoluteString;  

      

    // 2. 确定code=的范围  

    NSRange range = [urlStr rangeOfString:@"code="];  

      

    if (range.length != 0) {  

        // 授权成功,返回NO阻止其加载页面  

        NSUInteger index = range.location +range.length;  

          

        // 得到requestToken  

        NSString *requestToken = [urlStr substringFromIndex:index];  

        [self getAccessToken:requestToken];  

          

        return NO;  

    }  

      

    return YES; // 授权不成功,跳到回调地址kRedirectURI  

}  

3、用授权的RequestToken换取AccessToken



代码如下:

[objc] view
plaincopy

#pragma mark 用requestToken换取accessToken  

-(void)getAccessToken:(NSString *)requestToken  

{  

    [HttpTool postWithPath:@"oauth2/access_token" params:@{  

                       @"client_id":kAppKey,  

                       @"client_secret":kAppSecret,  

                       @"grant_type":@"authorization_code",  

                       @"redirect_uri":kRedirectURI,  

                       @"code":requestToken} success:^(id JSON) {  

                           // 保存accessToken  

                           AccessToken *accessToken = [[AccessToken alloc]init];  

                           accessToken.accessToken = JSON[@"access_token"];  

                           accessToken.uid = JSON[@"uid"];  

                             

                           [[AccessTokenTool sharedAccessTokenTool]saveAccessToken:accessToken];  

                             

                           // 回到主界面  

                           // ................................................  

                           self.view.window.rootViewController = [[MainViewController alloc]init];  

                             

                           // 隐藏加载动画  

                           [MBProgressHUD hideAllHUDsForView:self.view animated:YES];  

                       } failure:^(NSError *error) {  

                           [MBProgressHUD hideAllHUDsForView:self.view animated:YES];  

                       }];  

}  

三、归档、获取accessToken

当获取到accessToken后,将其归档存入本地文件中,下次直接从文件中获取accessToken,就不必再输入用户名密码登陆了。

1、首先封装accessToken为AccessToken对象,实现NSCoding协议和其中的方法

.h

[objc] view
plaincopy

#import <Foundation/Foundation.h>  

  

@interface AccessToken : NSObject <NSCoding>  

@property (copy, nonatomic) NSString *accessToken;  

@property (copy, nonatomic) NSString *uid;  

@end  

 

.m

[objc] view
plaincopy

#import "AccessToken.h"  

  

@implementation AccessToken  

  

#pragma mark 将accessToken,uid归档  

-(void)encodeWithCoder:(NSCoder *)aCoder  

{  

    [aCoder encodeObject:_accessToken forKey:@"accessToken"];  

    [aCoder encodeObject:_uid forKey:@"uid"];  

}  

  

#pragma mark 解档  

-(id)initWithCoder:(NSCoder *)aDecoder  

{  

    if (self = [super init]) {  

        self.accessToken = [aDecoder decodeObjectForKey:@"accessToken"];  

        self.uid = [aDecoder decodeObjectForKey:@"uid"];  

    }  

    return self;  

}  

  

@end  

2、实现工具类,其他对象只能通过该工具类获取accessToken,而且该工具类在整个项目中只需创建一次,用单例模式实现

.h

[objc] view
plaincopy

#import <Foundation/Foundation.h>  

#import "AccessToken.h"  

  

@interface AccessTokenTool : NSObject  

  

+(AccessTokenTool *)sharedAccessTokenTool;  

  

-(void)saveAccessToken:(AccessToken *)accessToken;  

  

// 当前accessToken  

@property (readonly, nonatomic)AccessToken *currentAccessToken;  

  

@end  

.m

[objc] view
plaincopy

#import "AccessTokenTool.h"  

#import "AccessToken.h"  

  

// 归档文件路径  

#define kFilePath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"accessToke.data"]  

  

static AccessTokenTool *_instace; // 静态实例  

  

@implementation AccessTokenTool  

  

+(AccessTokenTool *)sharedAccessTokenTool  

{  

    @synchronized(self){  

        if (_instace == nil) {  

            _instace = [[self alloc]init];  

        }  

    }  

      

    return _instace;  

}  

  

#pragma mark 重写allocWithZone方法  

+(id)allocWithZone:(struct _NSZone *)zone  

{  

    static dispatch_once_t onceToken;  

    dispatch_once(&onceToken, ^{  

        _instace = [super allocWithZone:zone];  

    });  

      

    return _instace;  

}  

  

#pragma mark 重写init方法  

-(id)init  

{  

    if (self = [super init]) {  

        _currentAccessToken = [NSKeyedUnarchiver unarchiveObjectWithFile:kFilePath];  

    }  

      

    return self;  

}  

  

-(void)saveAccessToken:(AccessToken *)accessToken  

{  

    _currentAccessToken = accessToken;  

    [NSKeyedArchiver archiveRootObject:accessToken toFile:kFilePath];  

}  

  

@end  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: