sina微博oauth第三方 登录

SDK:https://github.com/JimLiu/WeiboSDK

这篇文章具体谈谈在iOS上如何通过新浪微博账户登录应用。

在讨论这个之前,不得不说到OAuth。这是个什么玩意呢?按照官方的说法,OAuth是:An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

大概意思是说OAUTH是一种开放的协议,为桌面程序或者基于BS的web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。

也就是说,通过OAuth,应用或者网站服务可以获取用户的授权,但又不会获取到用户的账户信息(比如登录名和密码)。这里的授权包括:允许向用户发送某些信息,允许向用户提供访问网站的权限等等。

其实,对于大部分应用来说,只需要验证用户是否属于新浪微博用户,如果属于,那也自动是我的用户,如果不属于,那么请用户就地注册一个账户。换句话说,你将新浪微博的几亿用户自动承认成为你的网站用户,而不需要这几亿用户通过注册才能使用你的应用。所以,这是典型的一种YY思想,YY你瞬间获得了几亿用户!!

既然OAuth是一个协议,那么就需要用编程语言去实现它。目前,各种版本的OAuth基本都可以在google code下载到,包括C,C++,C#,JS,PHP等等。当然,肯定会有objective-C,否则,我也不会写这篇文章了。

OK,假设已经有了一个版本的Objective-C的OAuth的实现。下面就利用它来实现微博账户在iOS上的登录。

第一步:注册应用。

可以通过新浪微博的开放平台去注册一个应用。之后你会得到一个App Key和一个App Secret。拥有它们,你才可以申请权限。

假设你的App Key是“1234567890”,App Secret是“abcdefghijklmnopqrstuvwxyz"

第二步:写代码。

将获取到的OAuth的objective-C版本加入你的project中。将你申请到的Key和Secret做为两个变量定义并赋值。

对于OAuth来说,很多细节不需要我们去关注的,只要知道几个重要的步骤即可:

1. 创建一个request,这个request包含key和secret的信息,用于向新浪微博申请获得对应用户的权限。

2. 通过request向新浪微博发出请求,告诉新浪微博说:我是一个合法的注册过的应用,现在准备向大人您申请获得用户的权限,请您高抬贵手。

3. 获得未授权的 Request Key。这个获得未授权的 Request Key就相当于放行条,也就是新浪微博允许你开始获取用户的权限。

4. 根据这个Request Key的内容,获得一个url地址,这个地址页面就是想登录你应用的用户输入用户名和密码的地方。注意的是,这个url是属于新浪微博为你的这个应用创建的,是属于新浪微博的。调用iOS的接口,从浏览器打开这个url界面。

5. 用户在上述登录界面输入自己的用户名和密码,成功登录之后(其实是新浪微博认证此用户是注册了新浪微博的用户),你可以获得已授权的 Access KEY。这个Access Key就包含了用户多登录信息(包括昵称、用户ID等等,这里的昵称是指用户显示在新浪微博上的名字,而不是用户的登录名)。

6. 到目前为止,你已经确定用户是新浪微博的用户了,自然也是你的应用的用户(继续YY),所以接下去,你就赶紧允许用户登录成功,进入你的应用主界面,享受你的应用程序了。还愣着干嘛,翠花,上酸菜!!

    找到一个objective-c实现的OAuth,并且对着每一步(第六步除外,第六步是在你自己的project中实现。你总不能让OAuth给你上酸菜吧),找到实现每一步功能的函数,然后加入你自己的project中。



代码:


#import <Foundation/Foundation.h>

@interface SinaCodePathAndDic : NSObject
+(NSString *)writeToFilePath;

+(NSMutableDictionary *)code;
@end

#import "SinaCodePathAndDic.h"

@implementation SinaCodePathAndDic
+(NSString *)writeToFilePath
{
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinacode.plist"];
    return fileName;
}

+(NSMutableDictionary *)code
{
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinacode.plist"];
   
    NSMutableDictionary * codeDic = [NSMutableDictionary dictionaryWithContentsOfFile:fileName];
   
    return codeDic;
}

@end

#import <Foundation/Foundation.h>

#define SinaAppkey @"309949296"
#define SinaAppSecret @"a86376995071dc71a8616035c3d89176"
#define SinaCOMEBACK_URL @"http://www.m-bao.com"

#define URL_Authorize    @"https://api.weibo.com/oauth2/authorize"        ////使用浏览器授权request token (这个url加上参数在浏览器执行)
#define URL_Access        @"https://api.weibo.com/oauth2/access_token"  //获取access token
#define URL_SHARE_TEXT @"http://api.t.sina.com.cn/statuses/update.json"
#define URL_SHARE_PIC @"https://api.weibo.com/2/statuses/upload.json"



#define TOKEN_USER_ID    @"token_userId"
#define TOKEN_PREFIX    @"token_weibo"
#define TOKEN_PROVIDER    @"token_sina"

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>



@interface SinaShareURL : NSObject{
   
 
}

-(id)initWithText:(NSString *)text_;
-(id)initWithText:(NSString *)text_ andPic:(UIImage *)pic_;
+(BOOL)isDic;


@end
#import "SinaShareURL.h"
#import "SinaKey.h"
#import "SinaToken.h"
#import "URLEncode.h"
#import "JSON.h"
#define SHAREURL @"https://api.weibo.com/2/statuses/repost.json"


@implementation SinaShareURL




+(BOOL)isDic
{
    NSDictionary * DIC=[NSDictionary dictionaryWithDictionary:[SinaToken userDataAndToken]];
    if (![DIC valueForKey:@"access_token"])
    {
        return NO;
    }
    return YES;
}

-(id)initWithText:(NSString *)text_
{
    NSDictionary * DIC=[NSDictionary dictionaryWithDictionary:[SinaToken userDataAndToken]];
    NSURL * url_ = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.weibo.com/2/statuses/update.json?access_token=%@",[DIC valueForKey:@"access_token"]]];
   
    NSString * str_ = [NSString stringWithFormat:@"status=%@",[URLEncode encodeUrlStr:text_]];
    NSData * data = [str_ dataUsingEncoding:NSUTF8StringEncoding];
   
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url_];
   
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:data];
   
   
    [NSURLConnection connectionWithRequest:request delegate:self];
   
    return self;
}

-(id)initWithText:(NSString *)text_ andPic:(UIImage *)pic_
{
    NSDictionary * DIC=[NSDictionary dictionaryWithDictionary:[SinaToken userDataAndToken]];
   
    NSURL * url_ = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.weibo.com/2/statuses/upload.json?access_token=%@",[DIC valueForKey:@"access_token"]]];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url_];
    UIImage * image_ = pic_;
   
    NSData * imgData_ = UIImageJPEGRepresentation(image_, 0);
   
    NSString *boundary = @"AAAVVVAAA";
    NSString *boundaryEnd = [NSString stringWithFormat:@"\r\n--%@--\r\n",boundary];
    NSString *Content_Type = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
   
    NSMutableString *bodyString = [NSMutableString stringWithCapacity:100];
    [bodyString appendFormat:@"--%@",boundary];
    [bodyString appendString:@"\r\nContent-Disposition: form-data; name="status"\r\n\r\n"];
    if (text_) {
        [bodyString appendString:[URLEncode encodeUrlStr:text_]];
    }
    else{
        [bodyString appendString:[URLEncode encodeUrlStr:@"  "]];
       
    }
    [bodyString appendFormat:@"\r\n--%@",boundary];
    [bodyString appendString:@"\r\nContent-Disposition: form-data; name="pic"; filename="image.jpg"\r\nContent-Type: image/jpeg\r\n\r\n"];
   
    //data
    NSMutableData *bodyDataWithPic = [NSMutableData dataWithData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
    [bodyDataWithPic appendData:imgData_];
    [bodyDataWithPic appendData:[boundaryEnd dataUsingEncoding:NSUTF8StringEncoding]];
   
    //set header
    [request setValue:Content_Type forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d",[bodyDataWithPic length]] forHTTPHeaderField:@"Content-Length"];
   
    [request setHTTPBody:bodyDataWithPic];
    [request setHTTPMethod:@"POST"];
   
    [NSURLConnection connectionWithRequest:request delegate:self];
    return self;
   
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"asd=%@",[str JSONValue]);
    //    NSLog(@"111%@",data);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //    NSString * str = [[NSString alloc] initWithData:data_ encoding:NSUTF8StringEncoding];
    //    NSLog(@"asd=%@",[str JSONValue]);
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

@end
#import <Foundation/Foundation.h>
@protocol SinaTokenDeletage <NSObject>

- (void)tokenSaveOkayForSina;

@end
@interface SinaToken : NSObject{
    NSMutableData * data;
    id<SinaTokenDeletage>deletage;
}

@property (nonatomic,assign) id<SinaTokenDeletage>deletage;

- (void)getToken;
-(void)removeToken;

+(NSString *)writeToFilePath;

+(NSMutableDictionary *)userDataAndToken;

@end
#import "SinaToken.h"
#import "SinaUrl.h"
#import "JSON.h"
@implementation SinaToken
@synthesize deletage;
- (void)dealloc
{
    if (data) {
        [data release];
    }
    [super dealloc];
}
+(NSString *)writeToFilePath
{
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinauser.data"];
    return fileName;
}

+(NSMutableDictionary *)userDataAndToken
{
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinauser.data"];
   
    NSData * data = [NSData dataWithContentsOfFile:fileName];
   
    NSString * dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
   
    NSMutableDictionary * userDic = [dataStr JSONValue];
    NSLog(@"%@",userDic);
   
    return userDic;
}

- (void)getToken
{
    data = [[NSMutableData alloc] init];
   
    NSURL * url_ = [NSURL URLWithString:[SinaUrl SinaGetToKenURLString]];
   
    NSLog(@"cc=%@",[SinaUrl SinaGetToKenURLString]);
   
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url_];
    [request setHTTPMethod:@"POST"];
    [NSURLConnection connectionWithRequest:request delegate:self];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)_data
{
//    NSLog(@"22222%@",data);
    [data appendData:_data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
     NSLog(@"!!!!!!!!!!!%@,",data);
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinauser.data"];
   
    NSLog(@"%@,",data);
    [data writeToFile:fileName atomically:YES];
   
    if (deletage) {
        [deletage tokenSaveOkayForSina];
    }
}
-(void)removeToken
{
    NSFileManager* fileManager = [NSFileManager defaultManager];
    NSString *fileName=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sinauser.data"];
    [fileManager removeItemAtPath:fileName error:nil];
   
    NSLog(@"%@",fileName);
   
}
@end
#import <Foundation/Foundation.h>
#import "SinaKey.h"
@interface SinaUrl : NSObject{}


+(NSString *)SinaUrlString;
+(NSString *)SinaGetToKenURLString;
//+(NSString *)SinaShareUrlString;

@end
#import "SinaUrl.h"
#import "SinaCodePathAndDic.h"
@implementation SinaUrl
+(NSString *)SinaUrlString{
    NSString * parameter = @"";
   
    NSMutableArray * urlArray = [[NSMutableArray alloc] init];
    [urlArray addObject:[NSString stringWithFormat:@"client_id=%@",SinaAppkey]];
    [urlArray addObject:[NSString stringWithFormat:@"redirect_uri=%@",SinaCOMEBACK_URL]];
    [urlArray addObject:[NSString stringWithFormat:@"display=%@",@"mobile"]];
    for (int i=0; i<[urlArray count]; i++) {
       
        if (i==0) {
            parameter = [[parameter stringByAppendingString:@"?"] stringByAppendingString:[urlArray objectAtIndex:i]];
        }else{
            parameter = [[parameter stringByAppendingString:@"&"] stringByAppendingString:[urlArray objectAtIndex:i]];
        }
    }
   
    NSString * urlString = [URL_Authorize copy];
   
    urlString = [urlString stringByAppendingString:parameter];
   
    [urlArray release];
   
    return urlString;

}
+(NSString *)SinaGetToKenURLString
{
    NSString * parameter = @"";
   
    NSMutableArray * urlArray = [[NSMutableArray alloc] init];
    [urlArray addObject:@"grant_type=authorization_code"];
    [urlArray addObject:[NSString stringWithFormat:@"code=%@",[[SinaCodePathAndDic code] objectForKey:@"code"]]];
    [urlArray addObject:[NSString stringWithFormat:@"client_id=%@",SinaAppkey]];
    [urlArray addObject:[NSString stringWithFormat:@"redirect_uri=%@",SinaCOMEBACK_URL]];
    [urlArray addObject:[NSString stringWithFormat:@"client_secret=%@",SinaAppSecret]];
   
    for (int i=0; i<[urlArray count]; i++) {
       
        if (i==0) {
            parameter = [[parameter stringByAppendingString:@"?"] stringByAppendingString:[urlArray objectAtIndex:i]];
        }else{
            parameter = [[parameter stringByAppendingString:@"&"] stringByAppendingString:[urlArray objectAtIndex:i]];
        }
    }
   
    NSString * urlString = [URL_Access copy];
   
    urlString = [urlString stringByAppendingString:parameter];
   
    return urlString;

   
}
@end
#import <UIKit/UIKit.h>
#import "MainViewController.h"
@protocol SinaWebViewControllerDeletage <NSObject>

- (void)hasCodeForSina;

@end

@interface SinaWebViewController : MainViewController<UIWebViewDelegate>{
    UIWebView * web;
    NSMutableData * data;
    id<SinaWebViewControllerDeletage>deletage;
}
@property (nonatomic,assign) id<SinaWebViewControllerDeletage>deletage;
@end
#import "SinaWebViewController.h"
#import "SinaUrl.h"
#import "SinaCodePathAndDic.h"
@implementation SinaWebViewController
@synthesize deletage;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
-(void)dealloc
{
    [web release];
    [data release];
    [super dealloc];

}
- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
   
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle
-(void)popModeVC
{
    [self dismissModalViewControllerAnimated:YES];
}



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
   
   
    UINavigationBar * myBar_ = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    [myBar_ setTintColor:[UIColor orangeColor]];
   
    UINavigationItem * item_ = [[UINavigationItem alloc] initWithTitle:NSLocalizedString(@"新浪认证", nil)];
   
    UIBarButtonItem * buttonItem_ = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"返回", nil)
                                                              style:UIBarButtonItemStyleBordered
                                                             target:self
                                                             action:@selector(popModeVC)];
   
    item_.leftBarButtonItem = buttonItem_;
    [buttonItem_ release];
   
    [myBar_ pushNavigationItem:item_ animated:NO];
    [item_ release];
   
    [self.view addSubview:myBar_];   
    web = [[UIWebView alloc] initWithFrame:CGRectMake(0, 44, 320, 480)];
    [web setDelegate:self];
    NSURL * url = [NSURL URLWithString:[SinaUrl SinaUrlString]];
    NSLog(@"URL=%@",url);
    NSURLRequest * re = [NSURLRequest requestWithURL:url];
    [web loadRequest:re];
   
    data = [[NSMutableData alloc] init];
   
    [self.view addSubview:web];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
   
    NSString * urlStr=[[request URL] relativeString];     
    NSString * str=[[urlStr componentsSeparatedByString:@"?"] objectAtIndex:0];
    if ([str isEqualToString:@"http://www.m-bao.com/"]) {
       

        NSString * codeStr=[[[[urlStr componentsSeparatedByString:@"code="] objectAtIndex:1] componentsSeparatedByString:@"&"]objectAtIndex:0];
       
        NSMutableDictionary * codeDic = [NSMutableDictionary dictionary];
        [codeDic setValue:codeStr forKey:@"code"];
        NSLog(@"%@",codeStr);
        [codeDic writeToFile:[SinaCodePathAndDic writeToFilePath] atomically:YES];
       
        if (deletage) {
            [deletage hasCodeForSina];
        }
       
        [self dismissModalViewControllerAnimated:YES];
       
    }else
    {
    }
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [self webStartLoad];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [self webFinishLoad];
}



- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

你可能感兴趣的:(sina微博oauth第三方 登录)