亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

添加 Google API 離線訪問 .NET Core 應用程序

添加 Google API 離線訪問 .NET Core 應用程序

C#
達令說 2023-09-16 17:40:53
我編寫了一個 ASP.NET Core Web 應用程序,它使用 Auth0 作為用戶的主要授權機制,它中間人是一大堆外部身份驗證端點,例如 Google 和 Facebook。這工作得很好,我在那里沒有任何問題。該網絡應用程序的核心利用 Google Analytics 來執行自己的分析和業務邏輯。我的網絡應用程序正在分析的 Google Analytics 帳戶可能并且很可能與用戶自己的 Google 帳戶不同。需要明確的是,我的意思是,用戶很可能會使用他們希望的任何登錄提供商登錄,然后他們將附加一個特定的 Google 企業帳戶,可以訪問其企業的 Google Analytics 系統。Web 應用程序在用戶登錄和離線時執行分析。因此,我始終將用戶身份驗證 (Auth0) 步驟與 Analytics 帳戶步驟的身份驗證分開。大致流程如下:用戶使用任何提供商(Google、Facebook、電子郵件/通行證)通過 Auth0 登錄并訪問私人儀表板。用戶設置一個“公司”并單擊一個按鈕來授權我們的網絡應用程序訪問帶有 Analytics 的特定 Google 帳戶。用戶將被重定向回私人儀表板,并且 Google 帳戶的刷新令牌將被存儲以供將來使用。之前我也通過 Auth0 推送 Analytics 身份驗證,并且使用緩存的 Auth0 刷新令牌來離線工作。然而,它會在幾天后過期,并且 Auth0 似乎不提供長期離線訪問。因此,我認為最簡單的方法就是不使用 auth0 進行 Analytics 身份驗證步驟,直接使用 Google API 進行身份驗證并長期存儲 Google 刷新令牌。但是我找不到任何具體的例子來說明如何實現這一目標!
查看完整描述

1 回答

?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

我終于破解了!我最終扔掉了所有庫,發現使用普通的舊 REST API 最簡單。對于那些好奇的人來說,下面的代碼示例:


用戶的瀏覽器獲取以下內容并重定向到 Google 以獲取身份驗證令牌:


public IActionResult OnGet([FromQuery]int id, [FromQuery]string returnAction)

{

    var org = context.Organizations.Include(o => o.UserOrgs).First(o => o.Id == id);

    var user = GetUser();


    if (!IsUserMemberOfOrg(user, org)) return BadRequest("User is not a member of this organization!");


    var redirectUri = Uri.EscapeUriString(GetBaseUri()+"dash/auth/google?handler=ReturnCode");

    var uri = $"https://accounts.google.com/o/oauth2/v2/auth?"+

            $"scope={Uri.EscapeUriString("https://www.googleapis.com/auth/analytics.readonly")}"+

            $"&prompt=consent"+

            $"&access_type=offline"+

            //$"&include_granted_scopes=true"+

            $"&state={Uri.EscapeUriString(JsonConvert.SerializeObject(new AuthState() { OrgId = id, ReturnAction = returnAction }))}"+

            $"&redirect_uri={redirectUri}"+

            $"&response_type=code"+

            $"&client_id={_configuration["Authentication:Google:ClientId"]}";


    return Redirect(uri);

}

Google 重定向回以下內容,此時我從網絡服務器到 Google API 執行 POST,以將身份驗證令牌交換為刷新令牌并將其存儲以供以后使用:


public async Task<IActionResult> OnGetReturnCode([FromQuery]string state, [FromQuery]string code, [FromQuery]string scope)

{

    var authState = JsonConvert.DeserializeObject<AuthState>(state);


    var id = authState.OrgId;

    var returnAction = authState.ReturnAction;


    var org = await context.Organizations.Include(o => o.UserOrgs).SingleOrDefaultAsync(o => o.Id == id);

    if (org == null) return BadRequest("This Org doesn't exist!");

    using (var httpClient = new HttpClient())

    {

        var redirectUri = Uri.EscapeUriString(GetBaseUri()+"dash/auth/google?handler=ReturnCode");


        var dict = new Dictionary<string, string>

        {

            { "code", code },

            { "client_id", _configuration["Authentication:Google:ClientId"] },

            { "client_secret", _configuration["Authentication:Google:ClientSecret"] },

            { "redirect_uri", redirectUri },

            { "grant_type", "authorization_code" }

        };


        var content = new FormUrlEncodedContent(dict);

        var response = await httpClient.PostAsync("https://www.googleapis.com/oauth2/v4/token", content);


        var resultContent = JsonConvert.DeserializeObject<GoogleRefreshTokenPostResponse>(await response.Content.ReadAsStringAsync());


        org.GoogleAuthRefreshToken = resultContent.refresh_token;

        await context.SaveChangesAsync();


        return Redirect($"{authState.ReturnAction}/{authState.OrgId}");

    }

}

最后,我們可以稍后使用刷新令牌獲取新的訪問令牌,而無需用戶干預:


public async Task<string> GetGoogleAccessToken(Organization org)

{

    if(string.IsNullOrEmpty(org.GoogleAuthRefreshToken))

    {

        throw new Exception("No refresh token found. " +

            "Please visit the organization settings page" +

            " to setup your Google account.");

    }


    using (var httpClient = new HttpClient())

    {

        var dict = new Dictionary<string, string>

        {

            { "client_id", _configuration["Authentication:Google:ClientId"] },

            { "client_secret", _configuration["Authentication:Google:ClientSecret"] },

            { "refresh_token", org.GoogleAuthRefreshToken },

            { "grant_type", "refresh_token" }

        };

        var resp = await httpClient.PostAsync("https://www.googleapis.com/oauth2/v4/token", 

            new FormUrlEncodedContent(dict));


        if (resp.IsSuccessStatusCode)

        {

            dynamic returnContent = JObject.Parse(await resp.Content.ReadAsStringAsync());

            return returnContent.access_token;

        } else

        {

            throw new Exception(resp.ReasonPhrase);

        }

    }

}


查看完整回答
反對 回復 2023-09-16
  • 1 回答
  • 0 關注
  • 84 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號