zoukankan      html  css  js  c++  java
  • IOS OAuth授权分析

    一、黑马微博 ---> 用户的微博数据
    1.成为新浪的开发者(加入新浪微博的开发阵营)
    * 注册一个微博帐号,登录http://open.weibo.com
    帐号:643055866@qq.com
    密码:ios4762450
    * 填写开发者的个人信息(比如姓名、出生日期、上传身份证)

    2.创建应用
    * 假设应用名称叫做“黑马微博”
    * 应用创建完毕,默认就进入“开发”阶段,就具备了授权的资格
    * 应用相关数据
    App Key:3141202626 // 应用的唯一标识
    App Secret:ee9de4d2431be061b22fe328332a5228
    Redirect URI:http://www.itheima.com

    3.用户对“黑马微博”进行资源授权----OAuth授权2.0
    1> 获取未授权的Request Token : 展示服务器提供商提供的登录页面
    * URL : https://api.weibo.com/oauth2/authorize
    * 参数
    client_id     true     string     申请应用时分配的AppKey // 得知道给哪个应用授权
    redirect_uri     true     string     授权回调地址 // 授权成功后跳转到哪个页面

    2> 获取授权过的Request Token
    * 授权成功后,自动跳转到回调页面,比如
    http://www.itheima.com/?code=eabdc03cc4cc51484111b1cfd9c4cd0b
    // 新浪会在回调页面后面拼接一个参数:授权成功后的Request Token

    3> 根据授权过的Request Token换取一个Access Token
    * URL : https://api.weibo.com/oauth2/access_token
    * 参数
    client_id     true     string     申请应用时分配的AppKey。
    client_secret     true     string     申请应用时分配的AppSecret。
    grant_type     true     string     请求的类型,填写authorization_code
    code     true     string     调用authorize获得的code值。
    redirect_uri     true     string     回调地址,需需与注册应用里的回调地址一致
    * 返回结果
    {
        "access_token" = "2.00vWf4GEUSKa7D739148f7608SXA9B";
        "expires_in" = 157679999;
        "remind_in" = 157679999;
        uid = 3758830533;
    }
    // uid == user_id == 当前登录用户的ID   == 用户的唯一标识

    {
        "access_token" = "2.00vWf4GEUSKa7D739148f7608SXA9B";
        "expires_in" = 157679999;
        "remind_in" = 157679999;
        uid = 3758830533;
    }

    * access_token和uid的去呗
    access_token : 1个用户给1个应用授权成功后,就获得对应的1个access_token,作用是:允许1个应用访问1个用户的数据
    uid:1个用户对应1个uid,每1个用户都有自己唯一的uid
    举例:
    张三
    李四

    应用1
    应用2

    张三给应用1、应用2授权成功了:1个uid、2个access_token
    李四给应用2授权成功了:1个uid、1个access_token
    上面操作:产生了2个uid,3个access_token

    二、授权过程中常见错误:
    1.invalid_request
    1> 没有传递必填的请求参数
    2> 请求参数不对
    3> URL中间留有空格

    2.invalid_client
    1> client_id的值传递错误(AppKey不对)

    3.redirect_uri_mismatch
    1> 回调地址不对

    三、授权帐号注意
    1.如果应用还没有经过新浪审核,只能访问自己或者其他15个测试帐号的微博数据

     

    授权code (HMOAuthViewController.m)

    #import "HMOAuthViewController.h"
    #import "MBProgressHUD+MJ.h"
    #import "AFNetworking.h"
    #import "HMTabBarViewController.h"
    #import "HMNewfeatureViewController.h"
    
    @interface HMOAuthViewController () <UIWebViewDelegate>
    
    @end
    
    @implementation HMOAuthViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        //1.创建UIWebView
        UIWebView * webView=[[UIWebView alloc]init];
        webView.frame=self.view.frame;
        [self.view addSubview:webView];
        
        //2.加载登录页面
        NSURL *url=[NSURL URLWithString:@"https://api.weibo.com/oauth2/authorize?client_id=881257207&redirect_uri=http://blog.sina.com.cn"];
        
        NSURLRequest *request=[NSURLRequest requestWithURL:url];
        [webView loadRequest:request];
        
        //3.设置代理
        webView.delegate=self;
    }
    
    #pragma mark - UIWebViewDelegate
    /**
     *UIWebView开始加载资源的时候调用(开始发送请求)
     *
     */
    -(void)webViewDidStartLoad:(UIWebView *)webView
    {
        [MBProgressHUD showMessage:@"正在加载中......"];
    }
    /**
     *UIWebView加载完毕的时候调用(请求完毕)
     *
     */
    -(void)webViewDidFinishLoad:(UIWebView *)webView
    {
        [MBProgressHUD hideHUD];
    }
    /**
     *UIWebView加载失败的时候调用(请求失败)
     *
     */
    -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
    {
        [MBProgressHUD hideHUD];
    }
    
    /**
     *UIWebView每当发送一个请求之前,都会先调用这个代理方法(询问代理允不允许加载这个请求)
     *
     *@param request     即将发送的请求
     *@reture Yes    允许加载   NO:禁止加载
     */
    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        //1.获得请求地址
        NSString  *url=request.URL.absoluteString;
        
        //2.判断url是否为回调地址
        /** ~~~~
         url = http://www.itheima.com/?code=a3db74011c311e629bafce3e50c25339
         range.location == 0
         range.length > 0
         */
        /**
         url =  https://api.weibo.com/oauth2/authorize
         range.location == NSNotFound
         range.length == 0
         */
        NSRange range=[url rangeOfString:@"http://blog.sina.com.cn/?code="];
        if(range.location!=NSNotFound)//是回调地址
        {
        //截取授权成功后的请求标记
            int from=range.location+range.length;
            NSString *code=[url substringFromIndex:from];
            
            //根据code获得一个accessToken
            [self accessTokenWithCode:code];
            
            //禁止加载回调页面
            return  NO;
        }
        
        
        return YES;
    
    }
    /**
     *根据code获得一个accessToken
     *
     *@param code 授权成功后的请求标记
     */
    -(void)accessTokenWithCode:(NSString *)code
    {
    
        //1.获得请求管理者
        AFHTTPRequestOperationManager *mgr=[AFHTTPRequestOperationManager manager];
        
        //2.封装请求参数
        NSMutableDictionary *params=[NSMutableDictionary dictionary];
        params[@"client_id"]=@"881257207";
        params[@"client_secret"]=@"0b8c34d4659d656834f827abfb3a1805";
        params[@"redirect_uri"]=@"http://blog.sina.com.cn";
        params[@"grant_type"]=@"authorization_code";
        params[@"code"]=code;
        
        //3.发送POST请求
        [mgr POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
            
            //隐藏HUD
            [MBProgressHUD hideHUD];
            HMLog(@"请求成功。。。。。");
            
            //存储授权成功的帐号信息
            NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
            NSString *filepth=[doc stringByAppendingPathComponent:@"account.plist"];
            [responseObject writeToFile:filepth atomically:YES];
            
            //切换控制器(可能去新特性	abBar)
            //如何知道第一次使用这个版本?比较上次的使用情况
            NSString * versionKey=(__bridge NSString*)kCFBundleVersionKey;
            
            //从沙盒中取出上次存储的软件版本号(取出用户上次的使用记录)
            NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
            NSString *lastVersion=[defaults objectForKey:versionKey];
            
            //获得当前打开软件的版本号
            NSString *currentVersion=[NSBundle mainBundle].infoDictionary[versionKey];
            
            
            UIWindow *window=[UIApplication sharedApplication].keyWindow;
            if([currentVersion isEqualToString:lastVersion])//当前版本号==上次使用的版本:显示HMTabBarViewController
            {
                window.rootViewController=[[HMTabBarViewController alloc]init];
            }
            else{//当前版本号 !=上次使用的版本:显示版本新特性
                window.rootViewController=[[HMNewfeatureViewController alloc]init];
                
                //存储这次使用的软件版本
                [defaults setObject:currentVersion forKey:versionKey];
                [defaults synchronize];
            }
            
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            //隐藏HUD
            [MBProgressHUD hideHUD];
            HMLog(@"请求失败--@",error);
        }];
    }
    /**
     Request failed: unacceptable content-type: text/plain
     */
    @end
    View Code

     调用code 信息

    #import "AppDelegate.h"
    #import "HMTabBarViewController.h"
    #import "HMNewfeatureViewController.h"
    #import "HMOAuthViewController.h"
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        
        application.statusBarHidden=NO;
        
        //1.创建窗口
        self.window=[[UIWindow alloc]init];
        self.window.frame=[UIScreen mainScreen].bounds;
        
        
        //2.设置窗口的根控制器
        NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
        NSString *filepath=[doc stringByAppendingPathComponent:@"account.plist"];
        NSDictionary *account=[NSDictionary dictionaryWithContentsOfFile:filepath];
        if(account){
            //如果知道第一次使用这个版本?比较上次的使用情况
            NSString *versionKey=(__bridge NSString *)kCFBundleVersionKey;
            
            //从沙盒中取出上次存储的软件版本号(取出用户上次的使用记录)
            NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
            NSString  *lastVersion=[defaults objectForKey:versionKey];
            
            //获得当前打开软件的版本号
            NSString *currentVersion=[NSBundle mainBundle].infoDictionary[versionKey];
            
            if([currentVersion isEqualToString:lastVersion])// 当前版本号 == 上次使用的版本:显示HMTabBarViewController
            {
                self.window.rootViewController=[[HMTabBarViewController alloc]init];
            } else// 当前版本号 != 上次使用的版本:显示版本新特性
            {
                self.window.rootViewController= [[HMNewfeatureViewController alloc] init];
                
                //存储这次使用的软件版本
                [defaults setObject:currentVersion forKey:versionKey];
                [defaults synchronize];
            }
            
        }else{//没有登录过
            self.window.rootViewController=[[HMOAuthViewController alloc]init];
        }
        
        
        
        //3.显示窗口(成为主窗口)
        [self.window makeKeyAndVisible];
        
        return YES;
    }
  • 相关阅读:
    git学习总结
    vsftpd.conf配置详解
    网卡NAT方式下虚拟机安装FTP服务
    CentOS中vsftpd的主动和被动方式
    PHP面试总结
    虚拟机桥接网络连接方式
    虚拟机搭建ftp环境
    HTML5 WebSocket
    html5 postMessage解决跨域、跨窗口消息传递
    jqury-validate表单验证
  • 原文地址:https://www.cnblogs.com/liuwj/p/6658618.html
Copyright © 2011-2022 走看看