# 前言

在系统中使用常用的第三账号进行快捷登录是常用的方式,用户体验也比较友好。实现这种操作就要提到OAuth2

# OAuth2

OAuth2

# 使用 gitee 进行第三方登录

# 准备

  • 参考文档
  • 应用申请

# 流程

  1. 用户授权拿到 code (GET):
    • https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code

  2. 用户授权之后拿到 code, 获取 access_token:
    • https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=user_info

  3. 拿到第二步的 access_token 获取的用户信息:
    • https://gitee.com/api/v5/user?access_token={access_token}

# 代码实现

  • Http 工具类
public class HttpTo
    {
        /// <summary>
        /// HttpWebRequest 对象
        /// </summary>
        /// <param name="url"> 地址 </param>
        /// <param name="type"> 请求类型,默认 GET</param>
        /// <param name="data"> 发送数据,非 GET、DELETE 请求 </param>
        /// <param name="charset"> 编码,默认 utf-8</param>
        /// <returns></returns>
        public static HttpWebRequest HWRequest (string url, string type = "GET", string data = null, string charset = "utf-8")
        {
            var request = (HttpWebRequest) WebRequest.Create (url);
            request.Method = type;
            request.KeepAlive = true;
            request.AllowAutoRedirect = true;
            request.MaximumAutomaticRedirections = 4;
            request.Timeout = short.MaxValue * 3;//MS
            request.ContentType = "application/json; charset=utf-8";
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66";
            if (type != "GET" && type != "DELETE" && data != null)
            {
                // 发送内容
                byte [] bytes = Encoding.GetEncoding (charset).GetBytes (data);
                request.ContentLength = Encoding.GetEncoding (charset).GetBytes (data).Length;
                Stream outputStream = request.GetRequestStream ();
                outputStream.Write (bytes, 0, bytes.Length);
                outputStream.Close ();
            }
            return request;
        }
        /// <summary>
        /// HTTP 请求
        /// </summary>
        /// <param name="request">HttpWebRequest 对象 </param>
        /// <param name="charset"> 编码,默认 utf-8</param>
        /// <returns></returns>
        public static string Url (HttpWebRequest request, string charset = "utf-8")
        {
            try
            {
                var response = (HttpWebResponse) request.GetResponse ();
                Stream responseStream = response.GetResponseStream ();
                if (string.Compare (response.ContentEncoding, "gzip", true) >= 0)
                    responseStream = new System.IO.Compression.GZipStream (responseStream, System.IO.Compression.CompressionMode.Decompress);
                using var sr = new StreamReader (responseStream, Encoding.GetEncoding (charset));
                var result = sr.ReadToEnd ();
                return result;
            }
            catch (WebException e)
            {
                var httpResponse = (HttpWebResponse) e.Response;
                var errCode = (int) httpResponse.StatusCode;
                var result = string.Empty;
                if (e.Response == null)
                {
                    result = e.Response.ToString ();
                }
                else
                {
                    using Stream stream = e.Response.GetResponseStream ();
                    using var reader = new StreamReader (stream);
                    result = reader.ReadToEnd ();
                }
                Console.WriteLine ($"Error Code: {errCode}");
                Console.WriteLine (result);
                throw e;
            }
        }
        /// <summary>
        /// GET 请求
        /// </summary>
        /// <param name="url"> 地址 </param>
        /// <param name="charset"> 编码,默认 utf-8</param>
        /// <returns></returns>
        public static string Get (string url, string charset = "utf-8")
        {
            var request = HWRequest (url, "GET", null, charset);
            return Url (request, charset);
        }
        /// <summary>
        /// POST 请求
        /// </summary>
        /// <param name="url"> 地址 </param>
        /// <param name="data"> 发送数据 </param>
        /// <param name="charset"> 编码,默认 utf-8</param>
        /// <returns></returns>
        public static string Post (string url, string data, string charset = "utf-8")
        {
            var request = HWRequest (url, "POST", data, charset);
            return Url (request, charset);
        }
    }
  • 用户授权
[HttpGet("oauth/{type}")]
        public IActionResult Authorize(string type)
        {
            string CLIENTID = "48dc01efacf3b04139b4a52c86ff021a8921ffb2ec4337109941331ac690836e";
            string uuid = "teapus";
            string redirectUrl = "https://localhost:5006/oauth/giteecallback";
            String url = "https://gitee.com/oauth/authorize?response_type=code" +
            "&client_id=" + CLIENTID +
            "&redirect_uri=" + UrlEncode(redirectUrl) +
            //"&state=" + uuid +
            "&scope=user_info";
            return Redirect(url); ;
        }
  • 用户授权后回调
[HttpGet ("oauth/{type} callback")]
        public async Task<IActionResult> AuthorizeCallback (
            string type,
            [FromQuery] string code,
            [FromQuery] string state)
        {
            string AccessTokenUrl = "https://gitee.com/oauth/token";
            string UserInfoUrl = "https://gitee.com/api/v5/user";
            string CLIENTID = "48dc01efacf3b04139b4a52c86ff021a8921ffb2ec4337109941331ac690836e";
            string CLIENTSECRET = "282f9828b87765c0090715a62ec60f830b3cf548532f9c18d1803bd0d266a57d";
            string redirectUrl = "https://localhost:5006/oauth/giteecallback";
            string url = AccessTokenUrl + "?grant_type=authorization_code" +
                          "&client_id=" + CLIENTID +
                          "&client_secret=" + CLIENTSECRET +
                          "&code=" + code +
                          "&redirect_uri=" + redirectUrl;
            dynamic data = new
            {
                code = code
            };
            string json = JsonConvert.SerializeObject (data);
            // 拿到 access_token
            string result = HttpTo.Post (url, json);
            AccessToeknResult toeknResult = JsonConvert.DeserializeObject<AccessToeknResult>(result);
            // 获取用户信息
            string userInfoUrl = UserInfoUrl + "?access_token=" + toeknResult.access_token;
            string user = HttpTo.Get (userInfoUrl);
            UserInfo userInfo = JsonConvert.DeserializeObject<UserInfo>(user);
            string name = userInfo?.name;
            string email = userInfo?.email;
            string avatarUrl = userInfo?.avatar_url;
            
            // 这个回调路径是要返回前台的页面路径
            string callback = _Configuration ["frontEndCallback:Gitee:Url"];
            string frontUrl = $"{callback}?account={name}&type={type}";
            return Redirect (frontUrl);
        }

# 效果展示

# 效果页面

体验网址