zoukankan      html  css  js  c++  java
  • Github的第三方验证

    Github的第三方验证

    随着近年来网络安全越来越受到重视,对于用户认证和用户信息保存模块的开发也提升到了一个新的高度。
    一般小型网站开发的时候,由于技术水平和时间成本有限,很有可能会开发出一些或大或小的问题。幸好有许多第三方的OAuth服务可能帮我们简化这个问题。
    由于http://codesnippet.info/ 是一个技术网站,所以一般使用本网站的用户都会有Github账号。
    同时,通过获取Github账号的个人基本信息,对于用户之间的交流(Github的电子邮件),用户水平的了解(追随者数量)也有很大帮助。

    为你的网站申请APP第三方验证

    首先你必须要有一个Github的账号。如何申请Github的账号,这里就不需要再啰嗦了。
    注意这里的ClientID和SecretCode是整个OAuth的凭证,不要将这个信息泄露出去。

    • Application Name:应用名称(重要)
    • HomePageURL:网站的URL
    • ApplicationDescription:网站描述
    • Authorization callback URL:回调地址 (重要)

    关于回调地址,我原来有个误区,认为是Github服务器将数据Post到我的网站,就像微信公众平台那样,其实这里的回调地址是客户的浏览器发出的重定向地址。同时,这个地址是可以使用 localhost 的,这样的话对于我们调试程序会带来巨大的好处。

    第三方认证的开发

    认证按钮

    string clientid = "https://github.com/login/oauth/authorize?client_id=" + ConfigurationManager.AppSettings["ClientID"];
    

    整个认证的起始点是浏览器对于这个链接的访问,这里需要你的ClientID信息,这个信息是对所有人公开的。
    网站看上去是这个样子的
    https://github.com/login/oauth/authorize?client_id=01a8bf26baecfa8db577

    认证后的回调

    如果用户通过了验证,则浏览器将被重新定向到你定义的回调网址,同时会带上一个code参数
    你的程序需要将这个code参数,以及你的ClientID和SecretID来获得AccessToken。
    这里有几个地方必须注意:
    UserAgent必须有,而且是AppName!
    这个方法不能用Winform程序调试,因为这样可能造成一些跨域访问的问题。虽然使用Winform可以获得Code,但是AccessToken是无论如何也无法获得的!
    获得了AccessToken之后,可以获得用户的信息了,不过这个AccessToken不是写在获得用户信息的URL里面的,而是写在HTTPHEAD里面的。

           /// <summary>
            /// 获得login
            /// </summary>
            /// <param name="Code"></param>
            /// <returns></returns>
            public static GithubAccount GetUserInfo(string Code)
            {
                try
                {
                    var resonseJson = "";
                    var webRequest = WebRequest.Create(githubTokenUrl) as HttpWebRequest;
                    webRequest.Method = "POST";
                    webRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
                    //Github API V3必须加上下面这句话!
                    webRequest.UserAgent = AppName;
                    var postData = string.Format("code={0}&client_id={1}&client_secret={2}", Code, ClientID, ClientSecret);
    
                    //在HTTP POST请求中传递参数
                    using (var sw = new StreamWriter(webRequest.GetRequestStream()))
                    {
                        sw.Write(postData);
                        sw.Close();
                    }
    
                    //发送请求,并获取服务器响应
                    using (var response = webRequest.GetResponse())
                    {
                        using (var sr = new StreamReader(response.GetResponseStream()))
                        {
                            resonseJson = sr.ReadToEnd();
                        }
                    }
    
                    var resultparms = resonseJson.Split("&".ToCharArray());
                    var accessToken = string.Empty;
                    foreach (var parm in resultparms)
                    {
                        if (parm.StartsWith("access_token="))
                        {
                            accessToken = parm.Split("=".ToCharArray())[1];
                        }
                    }
    
                    webRequest = WebRequest.Create("https://api.github.com/user") as HttpWebRequest;
                    webRequest.Method = "GET";
                    webRequest.Headers.Add("Authorization", "token " + accessToken);
                    //Github API V3必须加上下面这句话!
                    webRequest.UserAgent = AppName;
    
                    using (var response = webRequest.GetResponse())
                    {
                        using (var sr = new StreamReader(response.GetResponseStream()))
                        {
                            dynamic obj = JsonConvert.DeserializeObject(sr.ReadToEnd());
                            GithubAccount gitlogin = new GithubAccount()
                            {
                                Login = obj.login,
                                Avatar_url = obj.avatar_url,
                                Email = obj.email,
                                Name = obj.name,
                                Html_url = obj.html_url,
                                Company = obj.company,
                                Blog = obj.blog,
                                Location = obj.location,
                                Followers = obj.followers,
                                Following = obj.following,
                                LastAccess = DateTime.Now
                            };
     						//省略
                    }
                }
                catch (Exception ex)
                {
                    InfraStructure.Log.ExceptionLog.Log("SYSTEM", "GitHubOAuth", "GET USER INFO", ex.ToString());
                    return null;
                }
            }
    

    个人基本信息

    从github账号中可以获得的个人基本信息如下:

    {
      "login": "magicdict",
      "id": 897796,
      "avatar_url": "https://avatars.githubusercontent.com/u/897796?v=3",
      "gravatar_id": "",
      "url": "https://api.github.com/users/magicdict",
      "html_url": "https://github.com/magicdict",
      "followers_url": "https://api.github.com/users/magicdict/followers",
      "following_url": "https://api.github.com/users/magicdict/following{/other_user}",
      "gists_url": "https://api.github.com/users/magicdict/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/magicdict/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/magicdict/subscriptions",
      "organizations_url": "https://api.github.com/users/magicdict/orgs",
      "repos_url": "https://api.github.com/users/magicdict/repos",
      "events_url": "https://api.github.com/users/magicdict/events{/privacy}",
      "received_events_url": "https://api.github.com/users/magicdict/received_events",
      "type": "User",
      "site_admin": false,
      "name": "MagicHu",
      "company": "Shanghai Chuwa software co.ltd",
      "blog": "http://www.mywechatapp.com",
      "location": "Shanghai,China",
      "email": "mynightelfplayer@hotmail.com",
      "hireable": true,
      "bio": null,
      "public_repos": 7,
      "public_gists": 0,
      "followers": 50,
      "following": 2,
      "created_at": "2011-07-06T09:26:40Z",
      "updated_at": "2016-02-06T09:09:34Z"
    }
    

    参考资料

    An introduction to the ASP.NET 5 Generic OAuth Provider

  • 相关阅读:
    快速上手php:使用PhpStrom调试php
    快速上手php:使用PhpStrom部署项目
    使用自定义tld标签简化jsp的繁琐操作
    京东购物体验杂谈
    Mysql将近两个月的记录合并为一行显示
    学习WebSocket(二):使用Spring WebSocket做一个简单聊天室
    学习WebSocket(一):Spring WebSocket的简单使用
    springMVC的@ResponseBody、@RequestBody使用需要注意的地方
    如何使用maven建一个web3.0的项目
    项目管理工具 Redmine 安装试用手记
  • 原文地址:https://www.cnblogs.com/TextEditor/p/5457379.html
Copyright © 2011-2022 走看看