gpt4 book ai didi

c# - 获取 ASP.NET MVC5 WebAPI token 有时会失败

转载 作者:行者123 更新时间:2023-11-30 20:20:23 25 4
gpt4 key购买 nike

获取 ASP.NET MVC5 WebAPI token 有时会失败

代码

string GetAPITokenSync(string username, string password, string apiBaseUri)
{
var token = string.Empty;

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.Timeout = TimeSpan.FromSeconds(60);

//setup login data
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password),
});

//send request
Task t = Task.Run(() =>
{
HttpResponseMessage responseMessage = client.PostAsync("/Token", formContent).Result;
var responseJson = responseMessage.Content.ReadAsStringAsync().Result;
var jObject = JObject.Parse(responseJson);
token = jObject.GetValue("access_token").ToString();
});

t.Wait();
t.Dispose();
t = null;
GC.Collect();

return token;
}
}

错误

One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
--- End of inner exception stack trace --- at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceled Exceptions) at System.Threading.Tasks.Task1.GetResultCore(Boolean
waitCompletionNotification) at
System.Threading.Tasks.Task
1.get_Result()

WebAPI登录方式默认没有变化。

[HttpPost]
[AllowAnonymous]
[Route("Login")]
public HttpResponseMessage Login(string username, string password)
{
try
{
var identityUser = UserManager.Find(username, password);

if (identityUser != null)
{
var identity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, username));

AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(1440));

var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);

var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
UserName = username,
ExternalAccessToken = token
}, Configuration.Formatters.JsonFormatter)
};

return response;


}
}
catch (Exception)
{
}

return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}

Startup 类默认没有变化

 public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

public static string PublicClientId { get; private set; }


public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
}

有什么线索吗?

最佳答案

很难确定,但是您阻止 HttpClient 调用的方式并没有帮助。 HttpClient 是一个异步库;你可能遇到了僵局。我建议摆脱所有 .Result.Wait() 并使用 async/await 异步编写所有内容。而您的 Task.Run 没有取得任何成果,所以应该结束。

我知道这是从控制台应用程序移植过来的 Topshelf 应用程序。我对 Topshelf 不是很熟悉,但我认为,与控制台应用程序一样,您需要在某处 进行阻止,否则您的应用程序将直接退出。执行此操作的位置位于最顶部 - 应用程序的入口点。

这演示了该模式,并重写了您的 GetApiToken 方法:

// app entry point - the only place you should block
void Main()
{
MainAsync().Wait();
}

// the "real" starting point of your app logic. do everything async from here on
async Task MainAsync()
{
...
var token = await GetApiTokenAsync(username, password, apiBaseUri);
...
}

async Task<string> GetApiTokenAsync(string username, string password, string apiBaseUri)
{
var token = string.Empty;

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.Timeout = TimeSpan.FromSeconds(60);

//setup login data
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password),
});

//send request
HttpResponseMessage responseMessage = await client.PostAsync("/Token", formContent);
var responseJson = await responseMessage.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseJson);
token = jObject.GetValue("access_token").ToString();

return token;
}
}

关于c# - 获取 ASP.NET MVC5 WebAPI token 有时会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36937328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com