AspDotnet Core实现第三方登录

Asp Dotnet Core 之第三方授权登录

1.环境准备

dotnetcore3 nginx做代理 路由器做内网映射

2.什么是第三方授权

​ 比如,有个网站,这个网站的登录方式有多种,可以自己注册登录,也可以利用qq等其他第三方的账户登录。这里的需求就是第三方授权。

3.和第三方服务器的协商

​ 为了完成上述的需求,我就开始了与第三方服务器的协商,第三方服务器告诉我,你得先在我这注册一个app,以便于我能知道是那些应用向我请求资源。我说没问题,于是就开始了注册,注册的时候,第三方服务器告诉我为了安全起见,我只允许特定ip来请求我的资源,我仔细一想,这说的没毛病,于是我就把我的项目的服务器的ip给了他。然后第三方服务器又说,你既然是请求用户的资源,那么肯定得经过用户的同意吧!我一想你说的对,第三方服务器给了我一个接口,说你带着注册app的appid,然后重定向到我这个接口,然后我就帮你询问用户是不是同意你访问他的资源,我说到:为啥要你提供接口,我问他不行嘛?第三方服务器告诉我,不行。我说,why?他说,万一你是骗子怎么办?用户不同意的让骗子给搞同意了。我说:说的有道理,那么,就按你说的办。然后第三方服务器又说了,你既然刚才重定向到我的接口了,那如果用户同意授权的话,我得在给你重定向回去啊!所以你在注册app的时候给我一个回调地址吧。我说ok,没毛病。然后我反问道,你给我回调的时候是直接把资源给我嘛?第三方服务器说:这不行,我会给你一个code,你那这个code去另一个接口换access_token吧!我说:老哥你弄怎么麻烦至于嘛。第三方服务器说:哎!兄弟,你有所不知,我的开发者对我进行了业务拆分,开发者说最近不是流行微服务嘛!然后就把授权这部分单独的给分出来了,我只能去颁发这个code,资源你得拿token去找我兄弟–第三方资源服务器。我说:好吧,你们搞得真复杂。第三方服务器说没办法啊!要想好的扩展性,只能做一些冗余的设计。我说:行。

​ 最后开发者发现上述流程整挺好,为了以后我们少干点活,干脆就把他固定下来。这样第三方授权就一个套路了。于是,上述流程就被起名–OAuth2协议(实际上是oauth协议的一部分)。

参考:https://www.cnblogs.com/wudimanong/p/10821215.html

​ https://blog.csdn.net/kefengwang/article/details/81213025

​ https://baike.baidu.com/item/OAuth2.0/6788617?fr=aladdin

在这里插入图片描述

4.第三方授权于id4的关系

​ 第三方服务器完成的app注册,用户确认授权,返回code,换access_token,这些东西id4都可以通过实现OAuth2协议来完成。所以id4与微服务,天然的cp

5.代码环境

  • 路由器做外网映射,将外网的ip和笔记本的ip做个映射

  • gitee/github注册app,ip地址填上述的外网ip

  • nginx监听内网做的映射的端口

    做外网映射而不是用服务器的目的是,服务器不好调试,不调试不太容易明白具体过程。

    用nginx做代理的目的是,方便看效果,就是你的程序不是实时在线,nginx可以,如果外网访问到了nginx那么只配置nginx就可以了。

6.代码实现

在这里插入图片描述

结构目录,采用的mvc项目,可以拆分为前后端分离。

view目录,里面放的是,前端页面

controller里面,是具体的业务逻辑

其他的不解释了。

回调接口

public async Task<string> Redict([FromQuery]string code, [FromQuery] string statu)
        {
            if (code != null)
            {
                //获得access_token
                var access_token = GetToken(code);

                 access_token = access_token.Replace("\\","");

                 var tokenobj = JsonConvert.DeserializeObject<GiteeToken>(access_token);

                //那token换信息
                var result = GetUserInfor(tokenobj.access_token);
                return result;
            }
            return "未成功";
        }

在回调接口里面接收code,然后调用GetToken获得token

GetToken函数

private string GetToken(string code)
        {
            //https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://gitee.com/oauth/token?grant_type=authorization_code");
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("grant_type", "");
            dic.Add("client_id", "971da916b01c4170b0ebf691a750f03747fe66f30c9fbc9cdf1f70f5915b5dfc");
            dic.Add("client_secret", "c3696974f93d2302f2289c6767dcaed8e411a8f01544158b41690215f0fed334");
            dic.Add("code", code);
            dic.Add("redirect_uri", "http://119.178.40.71:9000/OAuth/Redict_Gitee");
            #region 添加Post 参数
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

获得了token,就拿token换userinfor

GetUserInfor

private string GetUserInfor(string access_token)
        {

            string result = "";
            var request = (HttpWebRequest)WebRequest.Create("https://gitee.com/api/v5/user?access_token=" + access_token);
            request.Headers.Add("User-Agent", "AdminTest");
            request.Headers.Add("Authorization", access_token);
            HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

7.微软集成的服务

可爱的微软,当然贴心的为我们考虑到这种情况。微软将上述那些步骤做了个封装。让我们方便的使用第三方授权服务。

请参考博客:https://www.cnblogs.com/igeekfan/p/12110012.html

我们原理都明白了,第三方的实现还不手到擒来?

8.视频/源码参考

视频:正在审核

代码:https://gitee.com/qiujingbao/demo

发布了19 篇原创文章 · 获赞 7 · 访问量 4045

猜你喜欢

转载自blog.csdn.net/weixin_43906877/article/details/105334516