欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET?Core企業(yè)微信網(wǎng)頁授權登錄的實現(xiàn)

 更新時間:2022年04月22日 08:38:43   作者:微風吹過~  
本文主要介紹了.NET?Core企業(yè)微信網(wǎng)頁授權登錄的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

1.開發(fā)前準備

參數(shù)獲取

corpid

每個企業(yè)都擁有唯一的corpid,獲取此信息可在管理后臺“我的企業(yè)”-“企業(yè)信息”下查看“企業(yè)ID”

secret

secret是企業(yè)應用里面用于保障數(shù)據(jù)安全的“鑰匙”,每一個應用都有一個獨立的訪問密鑰,為了保證數(shù)據(jù)的安全,secret務必不能泄漏。

框架

例子使用yishaadmin開源框架為例

2.企業(yè)微信OAuth2接入流程

第一步: 用戶點擊連接

第二步: Index頁取得回調Code

第三步: 根據(jù)Code和access_token獲取UserID

第四步: 根據(jù)UserID到通訊錄接口獲取其他信息

3.構造網(wǎng)頁授權鏈接

假定當前企業(yè)CorpID:wxCorpId
訪問鏈接:http://api.3dept.com/cgi-bin/query?action=get

根據(jù)URL規(guī)范,將上述參數(shù)分別進行UrlEncode,得到拼接的OAuth2鏈接為:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxCorpId&redirect_uri=http%3a%2f%2fapi.3dept.com%2fcgi-bin%2fquery%3faction%3dget&response_type=code&scope=snsapi_base&state=#wechat_redirect

然后新建應用,將鏈接放入,配置應用可信域名。

官方文檔鏈接:https://developer.work.weixin.qq.com/document/path/91335

4. 調用代碼部分

4.1 appsettings配置

"Wx": {
    "corpid": "",
    "corpsecret": "",
    "baseurl": "https://qyapi.weixin.qq.com",
    "getUserByCode": "/cgi-bin/user/getuserinfo?access_token={0}&code={1}",
    "getToken": "/cgi-bin/gettoken?corpid={0}&corpsecret={1}",
    "getUserByUserId": "/cgi-bin/user/get?access_token={0}&userid={1}"
  }

4.2 配置IHttpClientFactory調用微信客戶端

public static IHttpClientFactory  httpClientFactory { get; set; }

Startup添加以下內容

public void ConfigureServices(IServiceCollection services)
 {
       services.AddHttpClient("WxClient", config => 
            {
                config.BaseAddress = new Uri(Configuration["Wx:baseurl"]);
                config.DefaultRequestHeaders.Add("Accept", "application/json");
            });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   GlobalContext.httpClientFactory = app.ApplicationServices.GetService<IHttpClientFactory>();
}

4.3 類準備

 UserCache 類保存用戶id,頭像,用戶名,以及code,按需新增。

using System;
using System.Collections.Generic;
using System.Text;

namespace YiSha.Model.Result
{
    public class UserCache
    {
        /// <summary>
        ///  用戶id
        /// </summary>
        public string UserID { get; set; }

        /// <summary>
        ///  頭像
        /// </summary>
        public string Portrait { get; set; }

        /// <summary>
        ///  用戶名
        /// </summary>
        public string Username { get; set; }

        /// <summary>
        ///  緩存最近一次Code 用于刷新時code不更新問題
        /// </summary>
        public string Code { get; set; }
    }
}

ApplicationContext用于緩存Token 過期時間以及用戶集合避免多次調用微信接口提高響應速度

using?System;using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YiSha.Model.Result;

namespace YiSha.Admin.Web.App_Code
{
    public static class ApplicationContext
    {
        /// <summary>
        ///  用于多點登錄的微信用戶
        /// </summary>
        public const string WxUser = "taskUser";

        /// <summary>
        /// 用于多點登錄的微信密碼
        /// </summary>
        public const string WxPassWord = "123456";

        /// <summary>
        /// 過期時間
        /// </summary>
        public static DateTime TimeOutDate { get; set; }

        /// <summary>
        /// Token
        /// </summary>
        public static string Token { get; set; }

        /// <summary>
        /// 緩存UserID Name 頭像
        /// </summary>
        public static List<UserCache> UserCache { get; set; } = new List<UserCache>();
    }
}

獲取Token返回實體

using System;
using System.Collections.Generic;
using System.Text;

namespace YiSha.Entity.OAManage
{
    public class GetTokenResult
    {

        /// <summary>
        /// 錯誤編號
        /// </summary>
        public int errcode { get; set; }

        /// <summary>
        /// 錯誤信息
        /// </summary>
        public string errmsg { get; set; }

        /// <summary>
        /// Token
        /// </summary>
        public string access_token { get; set; }

        /// <summary>
        /// 過期時間
        /// </summary>
        public int expires_in { get; set; }
    }
}

獲取用戶id返回實體

using System;
using System.Collections.Generic;
using System.Text;

namespace YiSha.Entity.OAManage
{
    //獲取用戶ID
    public class GetUserInfoResult
    {
        /// <summary>
        /// 錯誤編號
        /// </summary>
        public int errcode { get; set; }

        /// <summary>
        /// 錯誤信息
        /// </summary>
        public string errmsg { get; set; }

        /// <summary>
        /// 用戶ID
        /// </summary>
        public string UserID { get; set; }
    }
}

獲取用戶通訊錄返回實體

using System;
using System.Collections.Generic;
using System.Text;

namespace YiSha.Entity.OAManage
{
    public class GetUserResult
    {
        /// <summary>
        /// 錯誤編號
        /// </summary>
        public int errcode { get; set; }

        /// <summary>
        /// 錯誤信息
        /// </summary>
        public string errmsg { get; set; }

        /// <summary>
        /// 名稱
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 頭像
        /// </summary>
        public string avatar { get; set; }

    }
}

4.4方法準備

獲取Token方法,該方法對Token進行了一個緩存,避免重復獲取.

注意事項:
開發(fā)者需要緩存access_token,用于后續(xù)接口的調用(注意:不能頻繁調用gettoken接口,否則會受到頻率攔截)。當access_token失效或過期時,需要重新獲取。

access_token的有效期通過返回的expires_in來傳達,正常情況下為7200秒(2小時),有效期內重復獲取返回相同結果,過期后獲取會返回新的access_token。
由于企業(yè)微信每個應用的access_token是彼此獨立的,所以進行緩存時需要區(qū)分應用來進行存儲。
access_token至少保留512字節(jié)的存儲空間。
企業(yè)微信可能會出于運營需要,提前使access_token失效,開發(fā)者應實現(xiàn)access_token失效時重新獲取的邏輯。

獲取Token文檔鏈接https://developer.work.weixin.qq.com/document/path/91039

/// <summary>
        /// 獲取Token
        /// </summary>
        /// <returns>Item1 Token;Item2 是否成功</returns>
        public Tuple<string,bool> GetToken()
        {
            //判斷Token是否存在 以及Token是否在有效期內
            if(string.IsNullOrEmpty(ApplicationContext.Token) || ApplicationContext.TimeOutDate > DateTime.Now)
            {
                //構造請求鏈接
                var requestBuild = GlobalContext.Configuration["Wx:getToken"];
                requestBuild = string.Format(requestBuild,
                                  GlobalContext.Configuration["Wx:corpid"], 
                                  GlobalContext.Configuration["Wx:corpsecret"]
                               );
                using (var wxClient = GlobalContext.httpClientFactory.CreateClient("WxClient"))
                {
                   var httpResponse  = wxClient.GetAsync(requestBuild).Result;
                    if(httpResponse.StatusCode ==  System.Net.HttpStatusCode.OK)
                    {
                        var  dynamic= JsonConvert.DeserializeObject<GetTokenResult>(
                                          httpResponse.Content.ReadAsStringAsync().Result
                                          );

                        ApplicationContext.Token = dynamic.access_token;
                        //過期5分鐘前刷新Token
                        var expires_in = Convert.ToDouble(dynamic.expires_in - 5 * 60);
                        ApplicationContext.TimeOutDate = DateTime.Now.AddSeconds(expires_in);
                        return Tuple.Create(ApplicationContext.Token,true);
                    }
                    else
                    {
                        return Tuple.Create("獲取企業(yè)微信Token失敗,請稍后重試!", false);
                    }
                }
            }
            else
            {
                return Tuple.Create(ApplicationContext.Token, true);
            }
        }

獲取用戶ID方法,該方法根據(jù)獲取到的token,以及回調的code進行請求,得到用戶id實體

獲取訪問用戶身份文檔鏈接:https://developer.work.weixin.qq.com/document/path/91023

/// <summary>
        /// 獲取用戶ID
        /// </summary>
        /// <param name="token">企業(yè)微信Token</param>
        /// <param name="code">構造請求的回調code</param>
        /// <returns>Item1 UserId;Item2 是否成功</returns>
        public Tuple<string, bool> GetUserID(string token,string code)
        {
             //構造請求鏈接
             var requestBuild = GlobalContext.Configuration["Wx:getUserByCode"];
             requestBuild = string.Format(requestBuild,token,code);
             using (var wxClient = GlobalContext.httpClientFactory.CreateClient("WxClient"))
             {
                    var httpResponse = wxClient.GetAsync(requestBuild).Result;
                    if (httpResponse.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        var dynamic = JsonConvert.DeserializeObject<GetUserInfoResult>(
                                          httpResponse.Content.ReadAsStringAsync().Result
                                          );

                        return Tuple.Create(dynamic.UserID, true);
                    }
                    else
                    {
                        return Tuple.Create("獲取用戶ID失敗,請稍后重試!", false);
                    }
             }
            
        }

獲取用戶通訊錄方法,該方法可以通過token和userid進行獲取用戶頭像等信息,按需要調用

讀取成員接口文檔:https://developer.work.weixin.qq.com/document/path/90196

/// <summary>
        /// 獲取用戶通訊錄
        /// </summary>
        /// <returns>Item1 頭像,獲取失敗時為錯誤信息;Item2  名稱;Item3 是否成功</returns>
        public Tuple<string,string, bool> GetUserByID(string token, string userid)
        {
            //構造請求鏈接
            var requestBuild = GlobalContext.Configuration["Wx:getUserByUserId"];
            requestBuild = string.Format(requestBuild, token, userid);
            //建立HttpClient
            using (var wxClient = GlobalContext.httpClientFactory.CreateClient("WxClient"))
            {
                var httpResponse = wxClient.GetAsync(requestBuild).Result;
                if (httpResponse.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var dynamic = JsonConvert.DeserializeObject<GetUserResult>(
                                      httpResponse.Content.ReadAsStringAsync().Result
                                      );
                    return Tuple.Create(dynamic.avatar, dynamic.name, true);
                }
                else
                {
                    return Tuple.Create("獲取用戶ID失敗,請稍后重試!","", false);
                }
            }
        }

4.5調用

本方法是為了企業(yè)微信登錄時繞過用戶登錄直接使用企業(yè)微信用戶登錄,有其他需求根據(jù)需要調整。

主頁index 中使用code參數(shù)獲取回調傳進來的code,調用GetToken方法獲取Token,然后根據(jù)Token和Code獲取UserID,最后根據(jù)UserID和Token獲取通訊錄的頭像和名稱。需要注意的是我們要對每個用戶最新的code進行緩存,在企業(yè)微信內部瀏覽器時刷新code參數(shù)不會變動,但是code只能使用一次會導致接口調用失敗。

[HttpGet]
        public async Task<IActionResult> Index(string code)
        {
            OperatorInfo operatorInfo = default;
            TData<List<MenuEntity>> objMenu = await menuBLL.GetList(null);
            List<MenuEntity> menuList = objMenu.Data;
            menuList = menuList.Where(p => p.MenuStatus == StatusEnum.Yes.ParseToInt()).ToList();         
            if (code != null)//企業(yè)微信登錄
            {
                //獲取聯(lián)系人 從內存中取||從接口取
                string username, portrait = default;
                bool issuccess2 = default;

                //緩存最近的一次code  用于刷新URL時重復code請求失敗
                var codeCache =  ApplicationContext.UserCache.FirstOrDefault(o => o.Code == code);
                if(codeCache == null)
                {
                    //獲取token Token時間為過期時間減5分鐘
                    var (token, issuccess) = GetToken();
                    if (!issuccess) return RedirectToAction("error1", new { errormessage = token });
                    //獲取userid
                    var (userid, issuccess1) = GetUserID(token, code);
                    if (!issuccess1) return RedirectToAction("error1", new { errormessage = userid });

                    var useridCache = ApplicationContext.UserCache.FirstOrDefault(o => o.UserID == userid);
                    if (useridCache == null)//不存在緩存中
                    {
                        (portrait, username, issuccess2) = GetUserByID(token, userid);
                        if (!issuccess2) return RedirectToAction("error1", new { errormessage = portrait });
                        //加緩存
                        ApplicationContext.UserCache.Add(new UserCache()
                        { 
                           Code  = code,
                           Username = username,
                           Portrait = portrait,
                           UserID = userid
                        });

                        //保存登錄日志
                        var log = logLoginBLL.SaveForm(new LogLoginEntity
                        {
                            Remark = username,
                            ExtraRemark = token + ":" + userid
                        });
                    }
                    else//從緩存中獲取用戶信息
                    {
                        username = useridCache.Username;
                        portrait = useridCache.Portrait;
                        //更新最新code
                        useridCache.Code = code;
                    }
                }
                else
                {
                    username = codeCache.Username;
                    portrait = codeCache.Portrait;
                }
               
                //模擬登錄
                TData<UserEntity> userObj = await userBLL.CheckLogin(ApplicationContext.WxUser
                                                         , ApplicationContext.WxPassWord
                                                          , (int)PlatformEnum.Web);
                if (userObj.Tag == 1)
                {
                    await new UserBLL().UpdateUser(userObj.Data);
                    await Operator.Instance.AddCurrent(userObj.Data.WebToken);
                    var op = await Operator.Instance.Current();
                    AuthorizeListWhere(op);
                }
                //構建前端返回的用戶名 以及頭像
                operatorInfo = new OperatorInfo();
                operatorInfo.RealName = username;
                operatorInfo.UserName = username;
                operatorInfo.Portrait = portrait;
            }
            else//正常網(wǎng)頁登錄
            {

                operatorInfo = await Operator.Instance.Current();
                if (operatorInfo == null) return RedirectToAction("Login");
                if (operatorInfo.IsSystem != 1)
                {
                    AuthorizeListWhere(operatorInfo);
                }
            }

            //授權篩選
            void AuthorizeListWhere(OperatorInfo info)
            {
                TData<List<MenuAuthorizeInfo>> objMenuAuthorize = menuAuthorizeBLL.GetAuthorizeList(info).Result;
                List<long?> authorizeMenuIdList = objMenuAuthorize.Data.Select(p => p.MenuId).ToList();
                menuList = menuList.Where(p => authorizeMenuIdList.Contains(p.Id)).ToList();
            }
          
            new CookieHelper().WriteCookie("UserName", operatorInfo.UserName, false);
            new CookieHelper().WriteCookie("RealName", operatorInfo.RealName, false);
            ViewBag.OperatorInfo = operatorInfo;
            ViewBag.MenuList = menuList;
            return View();
        }

Index.Html調整

5.截圖

 到此這篇關于.NET Core企業(yè)微信網(wǎng)頁授權登錄的實現(xiàn)的文章就介紹到這了,更多相關.NET Core企業(yè)微信授權登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論