.NET平台史上最全的第三方登录开源整合库(包含钉钉、百度、支付宝、微信、企业微信等各大平台)...

34219159639c7208d6f1ce6ae33a2481.png

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!

项目介绍

CollectiveOAuth是一款.NET开源、最全的整合第三方登录的开源库。目前已包含Github、Gitee、钉钉、百度、支付宝、微信、企业微信、腾讯云开发者平台(Coding)、OSChina、微博、QQ、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、酷家乐、Gitlab、美团、饿了么、等第三方平台的授权登录。

4ff213ef9329daf327e897f1a7a42f63.png

环境支持

当前项目支持 .NET Framework 4.5 ~ 4.6.2 和 .NetCore 3.1。

各大平台API文档列表

  • https://gitee.com/rthinking/CollectiveOAuth#api%E5%88%97%E8%A1%A8

35c55f108ea528ab0ca190d0a4df11b6.png

处理微信开放平台的OAuth认证流程代码

这个类封装了与微信OAuth认证相关的所有步骤,包括用户授权、获取Access Token、获取用户信息以及Token的刷新。通过继承和重写DefaultAuthRequest类的方法,它提供了针对微信平台特定的实现。

using Come.CollectiveOAuth.Config;
using Come.CollectiveOAuth.Models;
using Come.CollectiveOAuth.Utils;
using System;
using System.Collections.Generic;
using Come.CollectiveOAuth.Enums;
using Come.CollectiveOAuth.Cache;

namespace Come.CollectiveOAuth.Request
{
    public partial class WeChatOpenAuthRequest : DefaultAuthRequest
    {
        public WeChatOpenAuthRequest(ClientConfig config) : base(config, new WechatOpenAuthSource())
        {
        }

        public WeChatOpenAuthRequest(ClientConfig config, IAuthStateCache authStateCache) 
            : base(config, new WechatOpenAuthSource(), authStateCache)
        {
        }

        /**
          * 微信的特殊性,此时返回的信息同时包含 openid 和 access_token
          *
          * @param authCallback 回调返回的参数
          * @return 所有信息
          */
        protected override AuthToken getAccessToken(AuthCallback authCallback)
        {
            return this.getToken(accessTokenUrl(authCallback.code));
        }

        protected override AuthUser getUserInfo(AuthToken authToken)
        {
            string openId = authToken.openId;

            string response = doGetUserInfo(authToken);
            var jsonObj = response.parseObject();

            this.checkResponse(jsonObj);

            //string location = String.format("%s-%s-%s", object.getString("country"), object.getString("province"), object.getString("city"));
            string location = $"{jsonObj.getString("country")}-{jsonObj.getString("province")}-{jsonObj.getString("city")}";
            if (jsonObj.ContainsKey("unionid"))
            {
                authToken.unionId = jsonObj.getString("unionid");
            }

            var authUser = new AuthUser();

            authUser.username = jsonObj.getString("nickname");
            authUser.nickname = jsonObj.getString("nickname");
            authUser.avatar = jsonObj.getString("headimgurl");
            authUser.location = location;
            authUser.uuid = openId;
            authUser.gender = GlobalAuthUtil.getWechatRealGender(jsonObj.getString("sex"));
            authUser.token = authToken;
            authUser.source = source.getName();

            authUser.originalUser = jsonObj;
            authUser.originalUserStr = response;

            return authUser;
        }

        public override AuthResponse refresh(AuthToken oldToken)
        {
            return new AuthResponse(Convert.ToInt32(AuthResponseStatus.SUCCESS), null, this.getToken(refreshTokenUrl(oldToken.refreshToken)));
        }

        /**
         * 检查响应内容是否正确
         *
         * @param object 请求响应内容
         */
        private void checkResponse(Dictionary<string, object> dic)
        {
            if (dic.ContainsKey("errcode"))
            {
                throw new Exception($"errcode: {dic.getString("errcode")}, errmsg: {dic.getString("errmsg")}");
            }
        }

        /**
         * 获取token,适用于获取access_token和刷新token
         *
         * @param accessTokenUrl 实际请求token的地址
         * @return token对象
         */
        private AuthToken getToken(string accessTokenUrl)
        {
            string response = HttpUtils.RequestGet(accessTokenUrl);
            var accessTokenObject = response.parseObject();

            this.checkResponse(accessTokenObject);

            var authToken = new AuthToken();

            authToken.accessToken = accessTokenObject.getString("access_token");
            authToken.refreshToken = accessTokenObject.getString("refresh_token");
            authToken.expireIn = accessTokenObject.getInt32("expires_in");
            authToken.openId = accessTokenObject.getString("openid");

            return authToken;
        }

        /**
         * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
         *
         * @param state state 验证授权流程的参数,可以防止csrf
         * @return 返回授权地址
         * @since 1.9.3
         */
        public override string authorize(string state)
        {
            return UrlBuilder.fromBaseUrl(source.authorize())
                .queryParam("appid", config.clientId)
                .queryParam("redirect_uri", GlobalAuthUtil.urlEncode(config.redirectUri))
                .queryParam("response_type", "code")
                .queryParam("scope", config.scope.IsNullOrWhiteSpace() ? "snsapi_login" : config.scope)
                .queryParam("state", getRealState(state))
                .build();
        }

        /**
         * 返回获取accessToken的url
         *
         * @param code 授权码
         * @return 返回获取accessToken的url
         */
        protected override string accessTokenUrl(string code)
        {
            return UrlBuilder.fromBaseUrl(source.accessToken())
                .queryParam("appid", config.clientId)
                .queryParam("secret", config.clientSecret)
                .queryParam("code", code)
                .queryParam("grant_type", "authorization_code")
                .build();
        }

        /**
         * 返回获取userInfo的url
         *
         * @param authToken 用户授权后的token
         * @return 返回获取userInfo的url
         */
        protected override string userInfoUrl(AuthToken authToken)
        {
            return UrlBuilder.fromBaseUrl(source.userInfo())
                .queryParam("access_token", authToken.accessToken)
                .queryParam("openid", authToken.openId)
                .queryParam("lang", "zh_CN")
                .build();
        }

        /**
         * 返回获取userInfo的url
         *
         * @param refreshToken getAccessToken方法返回的refreshToken
         * @return 返回获取userInfo的url
         */
        protected override string refreshTokenUrl(string refreshToken)
        {
            return UrlBuilder.fromBaseUrl(source.refresh())
                .queryParam("appid", config.clientId)
                .queryParam("grant_type", "refresh_token")
                .queryParam("refresh_token", refreshToken)
                .build();
        }
    }
}

开源地址

https://gitee.com/rthinking/CollectiveOAuth

35df3a6b7d312f1b3e5631f2f3b0fbbf.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值