您的位置:首页 > 其它

sina微博oauth第三方 登录

2012-12-17 10:36 253 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: