世华 發表於 2025-2-22 11:31:00

网站集成Github、Gitee登录

<p>在现代应用开发中,第三方登录是常见的功能,可以降低用户登录的门槛,所以我给我的我的网站集成 github、gitee 登录教程,今天来看看如何在.net core 中集成 ,代码比较简单,以此记录一下。</p>
<h2 id="github登录">Github登录</h2>
<h3 id="配置-github-认证">配置 GitHub 认证</h3>
<p>在 GitHub 上创建一个 应用,获取 Client ID 和 Client Secret。只需要在gitub的开发设置里面申请就好了,我觉得有的网站(包括gitee)第三方登录申请比较友好,直接注册,并且支持loaclhost的调试,大大的降低了难度。<br>
<img src="https://img2024.cnblogs.com/blog/994611/202502/994611-20250222112940970-1327282752.png"></p>
<h3 id="页面配置按钮">页面配置按钮</h3>
<p>页面配置按钮,点击登录图标跳转到https://gitee.com/oauth/authorize,这个地址是固定的<br>
代码如下</p>
<pre><code class="language-VUE">window.location.href = "https://github.com/login/oauth/authorize?client_id=" + appId;

</code></pre>
<p>其中appId是你申请的clientId<br>
跳转之后,会自动跳到你的回调页面然后携带一个code,然后你拿到这个code就可以<br>
获取accessToken了</p>
<h3 id="请求accesstoken">请求AccessToken</h3>
<p>请求后台接口,把code传过去</p>
<pre><code class="language-VUE"> const loading = loadService.openFullLoading('登录认证中...');
    let code = route.query.code;
    let loginType = route.query.openLoginType;
    let params = {
      code: code,
      loginType: loginType
    }
    openLoginApi(params).then(res =&gt; {
      window.location.href = import.meta.env.VITE_WEB_UI;
      loadService.closeFullLoading(loading);
    })
</code></pre>
<p>请求accessToken的接口是https://github.com/login/oauth/access_token</p>
<p>代码如下</p>
<pre><code class="language-c#">private async Task&lt;string&gt; GetAccessToken(string authorizationCode, string clientId, string clientSecret)
      {
            if (string.IsNullOrEmpty(authorizationCode))
                throw new AuthException("github认证登录失败:authorizationCode为空");
            string apiUrl = $"https://github.com/login/oauth/access_token?client_id={clientId}&amp;client_secret={clientSecret}&amp;code={authorizationCode}";
            HttpClient httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
            string response = await httpClient.GetStringAsync(apiUrl);
            dynamic result = JsonConvert.DeserializeObject(response);
            return result.access_token;
      }
</code></pre>
<p>其中 httpClient.DefaultRequestHeaders.Add("Accept", "application/json")你可以根据你的要求去设置header来得到的接口数据的格式</p>
<h3 id="请根据accesstoken获取用户信息">请根据AccessToken获取用户信息</h3>
<pre><code class="language-c#">private async Task&lt;GitHubUserInfo&gt; GetGitHubUser(string accessToken)
      {
            string apiUrl = "https://api.github.com/user";
            HttpClient httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("User-Agent", "xiandan");
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            string response = await httpClient.GetStringAsync(apiUrl);
            dynamic result = JsonConvert.DeserializeObject(response);
            GitHubUserInfo gitHubUserInfo = new GitHubUserInfo();
            gitHubUserInfo.LoginName= result.login;
            gitHubUserInfo.AvtarUrl= result.avatar_url;
            gitHubUserInfo.OpenID = result.id;
            gitHubUserInfo.OpenAuthEnum = OpenAuthEnum.GitHub;
            gitHubUserInfo.Sex = "男";
            return gitHubUserInfo;

      }
</code></pre>
<p>其中httpClient.DefaultRequestHeaders.Add("User-Agent", "xiandan"),如果你不设置User-Agent的话,可能会出现接口403的情况,具体的根据自己的情况处理</p>
<h3 id="保存用户信息并且登录">保存用户信息并且登录</h3>
<p>上面的方法返回了用户信息后,既可以执行你的业务操作了,如创建用户信息并且生成登录token,我的代码</p>
<pre><code class="language-c#"> public async Task&lt;LoginUser&gt; CreateOpenUser(BaseOpenUserInfo openUserInfo)
      {
            var accountRepository = unitOfWork.GetRepository&lt;Account&gt;();
            var userRepository = unitOfWork.GetRepository&lt;User&gt;();
            var uploadFileRepository = unitOfWork.GetRepository&lt;UploadFile&gt;();
            Account account = await accountRepository.SelectSingleAsync(s =&gt; s.AccountName == openUserInfo.OpenID);
            UploadFile avatarFile = null;
            User user = null;
            if (account == null)
            {
                RegisterUserDTO registerUserDto = CreateOpenUser(openUserInfo, ref avatarFile);
                var tup = CreateAccountUser(registerUserDto);
                account = tup.Item1;
                user = tup.Item2;
                await accountRepository.InsertAsync(account);
                await userRepository.InsertAsync(user);
                if (avatarFile != null)
                {
                  avatarFile.Id = CreateEntityId();
                  avatarFile.UserId = user.Id;
                  avatarFile.EntityId = user.Id;
                  await uploadFileRepository.InsertAsync(avatarFile);
                }
                await unitOfWork.CommitAsync();
            }
            else
            {
                user = await userRepository.SelectSingleAsync(s =&gt; s.AccountId == account.Id);
                avatarFile = await uploadFileRepository.SelectSingleAsync(s =&gt; s.EntityId == user.Id &amp;&amp; s.EntityName == EntityCode.UserEntityName);
            }
            LoginUser loginUser = CreateLoginUser(user, account, avatarFile);
            return loginUser;
      }
</code></pre>
<h2 id="gitee登录">Gitee登录</h2>
<p>gitee登录基本上和github登录差不多,也支持loaclhost的调试</p>
<pre><code class="language-vue">window.location.href = "https://gitee.com/oauth/authorize?client_id=" + clientId + "&amp;redirect_uri=" + redirectUri + "&amp;response_type=code";

</code></pre>
<pre><code class="language-language"> private async Task&lt;string&gt; GetAccessToken(string code)
      {
            string url = $"https://gitee.com/oauth/token";
            HttpClient client = new HttpClient();
            FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair&lt;string, string&gt;("grant_type","authorization_code"),
                new KeyValuePair&lt;string, string&gt;("code",code),
                new KeyValuePair&lt;string, string&gt;("client_id",GiteeConfigOption.ClientId),
                new KeyValuePair&lt;string, string&gt;("client_secret",GiteeConfigOption.ClientSecret),
                new KeyValuePair&lt;string, string&gt;("redirect_uri",GiteeConfigOption.RedirectUri)
            });
            HttpResponseMessage response = await client.PostAsync(url, content);
            if (response.IsSuccessStatusCode)
            {
                string responseBody = await response.Content.ReadAsStringAsync();
                dynamic tokenResponse = JsonConvert.DeserializeObject(responseBody);
                return tokenResponse.access_token;
            }
            else
            {
                throw new Exception($"获取访问令牌失败:{response.StatusCode}");
            }
      }
      private async Task&lt;GiteeUserInfo&gt; GetGiteeUserInfo(string accessToken)
      {
            string url ="https://gitee.com/api/v5/user?access_token="+accessToken;
            HttpClient httpClient = new HttpClient();
            string response=await httpClient.GetStringAsync(url);
            dynamic result = JsonConvert.DeserializeObject(response);
            GiteeUserInfo giteeUserInfo = new GiteeUserInfo();
            giteeUserInfo.OpenAuthEnum = OpenAuthEnum.Gitee;
            giteeUserInfo.OpenID = result.id;
            giteeUserInfo.Name= result.name;
            giteeUserInfo.AvatarUrl = result.avatar_url;
            giteeUserInfo.Sex = "男";
            return giteeUserInfo;
      }
</code></pre>
<p>这样,基本的.net core 集成 GitHub、gitee 登录就完成了。</p>
<blockquote>
<p>作者:程序员奶牛 <br><br>
个人开源网站:https://www.xiandanplay.com<br>
源码地址:https://gitee.com/MrHanchichi/xian-dan</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/MrHanBlog/p/18730730
頁: [1]
查看完整版本: 网站集成Github、Gitee登录