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

posted @ 2016-05-04 09:53  灰毛毛  阅读(7668)  评论(2编辑  收藏  举报