Blazor中基于RestSharp实现OAuth2:登录跳转及授权后API调用问题
解决Blazor中Infusionsoft OAuth2授权及API调用问题
嘿,我来帮你梳理下当前的问题——你的代码逻辑有个关键误区:OAuth2授权码流程的第一步是引导用户在浏览器里访问授权页面,而不是用RestSharp发送POST请求。RestSharp适合后续的令牌交换和API调用,而非初始化授权跳转。
1. 修正授权跳转逻辑
在Blazor里,你需要借助NavigationManager实现页面重定向,引导用户到Infusionsoft的授权页。具体步骤如下:
- 注入
NavigationManager服务 - 构造包含所有必填参数的授权URL
- 调用
NavigateTo方法完成跳转
示例代码:
@page "/infusionsoft" @inject NavigationManager NavManager @using System.Web; <button @onclick="RedirectToInfusionsoftAuth">授权登录Infusionsoft</button> @code { private void RedirectToInfusionsoftAuth() { var clientId = "myid"; var redirectUri = "https://your-blazor-app.com/infusionsoft-callback"; // 替换成你在Infusionsoft后台配置的回调地址 var scope = "full"; // 根据业务需求调整权限范围 var state = Guid.NewGuid().ToString(); // 用于防CSRF攻击,建议存到LocalStorage或Session // 构造符合OAuth2规范的授权URL var authUrl = $"https://signin.infusionsoft.com/app/oauth/authorize?client_id={HttpUtility.UrlEncode(clientId)}" + $"&redirect_uri={HttpUtility.UrlEncode(redirectUri)}" + $"&response_type=code" + $"&scope={HttpUtility.UrlEncode(scope)}" + $"&state={HttpUtility.UrlEncode(state)}"; // 强制跳转授权页面 NavManager.NavigateTo(authUrl, forceLoad: true); } }
2. 回调页面交换访问令牌
用户授权成功后,Infusionsoft会重定向到你配置的redirect_uri,并携带code(授权码)和state参数。此时你需要在回调页面(比如/infusionsoft-callback)用授权码交换访问令牌,这才是RestSharp的适用场景:
@page "/infusionsoft-callback" @inject NavigationManager NavManager @using RestSharp; @using Newtonsoft.Json; @code { protected override async Task OnInitializedAsync() { // 从URL中提取授权码和state参数 var uri = new Uri(NavManager.Uri); var code = HttpUtility.ParseQueryString(uri.Query).Get("code"); var state = HttpUtility.ParseQueryString(uri.Query).Get("state"); // 验证state(和之前存储的对比,防止CSRF攻击) // 示例省略state验证逻辑,实际开发中必须添加 if (!string.IsNullOrEmpty(code)) { var tokenUrl = "https://api.infusionsoft.com/token"; var clientId = "myid"; var clientSecret = "mysecret"; var redirectUri = "https://your-blazor-app.com/infusionsoft-callback"; // 必须和授权跳转时的地址一致 var restClient = new RestClient(tokenUrl); var request = new RestRequest(Method.Post); request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); request.AddParameter("client_id", clientId); request.AddParameter("client_secret", clientSecret); request.AddParameter("grant_type", "authorization_code"); request.AddParameter("code", code); request.AddParameter("redirect_uri", redirectUri); var response = await restClient.ExecuteAsync(request); if (response.IsSuccessful) { // 解析令牌响应 var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(response.Content); // 安全存储令牌(Blazor WebAssembly用LocalStorage,Server用Session) // 示例:await localStorage.SetItemAsync("access_token", tokenResponse.AccessToken); // 跳转至API调用页面 NavManager.NavigateTo("/infusionsoft-api"); } else { Console.WriteLine($"令牌交换失败:{response.Content}"); } } } // 定义令牌响应模型 public class TokenResponse { [JsonProperty("access_token")] public string AccessToken { get; set; } [JsonProperty("token_type")] public string TokenType { get; set; } [JsonProperty("expires_in")] public int ExpiresIn { get; set; } [JsonProperty("refresh_token")] public string RefreshToken { get; set; } } }
3. 授权后调用Infusionsoft API
拿到访问令牌后,只需在请求头中添加Bearer令牌,即可用RestSharp调用Infusionsoft的API:
@page "/infusionsoft-api" @inject ILocalStorageService localStorage // 假设使用Blazored.LocalStorage存储令牌 @using RestSharp; <button @onclick="CallInfusionsoftApi">调用联系人API</button> <p>API响应:@apiResponse</p> @code { private string apiResponse; private async Task CallInfusionsoftApi() { var accessToken = await localStorage.GetItemAsync<string>("access_token"); if (string.IsNullOrEmpty(accessToken)) { apiResponse = "未找到有效令牌,请先完成授权"; return; } var apiUrl = "https://api.infusionsoft.com/crm/rest/v1/contacts"; // 示例API端点 var restClient = new RestClient(apiUrl); var request = new RestRequest(Method.Get); // 添加Bearer授权头 request.AddHeader("Authorization", $"Bearer {accessToken}"); request.AddHeader("Accept", "application/json"); var response = await restClient.ExecuteAsync(request); if (response.IsSuccessful) { apiResponse = response.Content; } else { apiResponse = $"API调用失败:{response.StatusCode} - {response.Content}"; } } }
关键注意事项
- 确保在Infusionsoft开发者平台中配置的
redirect_uri和代码中的完全一致 - 必须验证
state参数,防范跨站请求伪造攻击 - 令牌需安全存储,Blazor WebAssembly中使用LocalStorage时注意敏感数据风险
- 记得处理令牌过期场景,用
refresh_token刷新访问令牌
内容的提问来源于stack exchange,提问作者Mark Daniel Louwe
相关产品推荐
相关产品推荐

