我正在尝试在我的C#Web应用程序中实现Google SSO。这似乎很简单。 基于本教程,谷歌在网络浏览器中发挥了魔力,以获得Id_Token JWT。 我将令牌传递给我的 Web 服务进行验证,并使用它来将其与应用程序中的用户匹配。
虽然我不确定我对服务器端 Google API 的方法是否正确,但我的大挂断是试图弄清楚如何使用 Google API 中的异步调用以查看我得到什么。
我的代码使用Google.Apis.Auth命名空间非常简单:
public async Task<GoogleJsonWebSignature.Payload> wfValidateAsync(string pId_Token)
{
GoogleJsonWebSignature.Payload Sig = await GoogleJsonWebSignature.ValidateAsync(pId_Token, null, false);
return Sig;
}
虽然这个异步/等待范式是全新的,但我确实在 AngularJS/NodeJS 承诺/回调方面有一些经验。 我的挑战是,似乎异步方法只能由其他异步方法一直调用,一直到调用堆栈。 我认为这意味着在异步响应完成并且服务可以对结果采取行动之前结束服务调用。
此外,为了创建单元测试,将异步放入 [TestMethod] 方法会使其从测试资源管理器中完全消失。我不确定如何测试/调试这个难题。
提前感谢任何可以帮助我把头拧回去的人。
虽然这个异步/等待范式是全新的,但我确实在 AngularJS/NodeJS 承诺/回调方面有一些经验。
但不要使用打字稿,对吧?
我的挑战是,似乎异步方法只能由其他异步方法一直调用,一直到调用堆栈。
他们应该。如果你不这样做,坏事就会发生。
我认为这意味着在异步响应完成并且服务可以对结果采取行动之前结束服务调用。
不!编译器使用async
修饰符为方法生成状态机,await
关键字表示"去做别的事情,完成后我会回到这里"。
此外,为了创建单元测试,将异步放入 [TestMethod] 方法会使其从测试资源管理器中完全消失。我不确定如何测试/调试这个难题。
您可能正在使您的测试方法async void
。应async Task
它们,以便测试引擎知道测试何时完成。
看看Stephen Cleary的博客。他在async-await
上有很多内容。
保罗,谢谢!!
我能够根据您对有关测试方法的最后一部分的建议来解决这个问题。 我不得不改变这一点:
//THIS TEST METHOD DOESN'T SHOW IN THE TEST EXPLORER
[TestMethod]
public async void AuthenticateGoogle()
{
string lToken = "[JWT TOKEN HERE]";
wfUser lUser = new wfUser(_wfContext);
var lAuthenticateResult = await lUser.wfAuthenticateGoogle(lToken);
Assert.IsTrue(lAuthenticateResult, "JWT Token Validated");
}
对此:
//THIS TEST METHOD SHOWS IN THE TEST EXPLORER
[TestMethod]
public async Task AuthenticateGoogle()
{
string lToken = "[JWT TOKEN HERE]";
wfUser lUser = new wfUser(_wfContext);
var lAuthenticateResult = await lUser.wfAuthenticateGoogle(lToken);
Assert.IsTrue(lAuthenticateResult, "JWT Token Validated");
}
现在 - 作为挂断我的另一个问题,这也会导致单元测试从测试资源管理器中消失,这是我通过懒惰复制/粘贴非测试方法的定义并在构建输出告诉我我需要返回值时盲目地添加返回来发现的。
//THIS TEST METHOD DOESN'T SHOW IN THE TEST EXPLORER DUE TO RETURN VALUE
[TestMethod]
public async Task<bool> AuthenticateGoogle()
{
string lToken = "[JWT TOKEN HERE]";
wfUser lUser = new wfUser(_wfContext);
var lAuthenticateResult = await lUser.wfAuthenticateGoogle(lToken);
Assert.IsTrue(lAuthenticateResult, "JWT Token Validated");
return true;
}
除了您分享的优秀博客之外,MSDN 杂志的这篇题为">异步编程:单元测试异步代码">的文章也帮助我了解了它。
所有这些让我感到困惑的是混合同步和异步方法,就你而言,这种方法效果不佳。代码似乎跳过了我在 await 调用后设置的调试点,就好像它从未运行过它们,或者,如果它确实运行了它们,则在我看不到且无法记录到调试器的地方运行它们。
这是周五晚上的可怕时刻之一,开发人员开始质疑能力和理智! :)
再次感谢您的帮助!
附言我在问题中错误地输入了Angular JS,意思是Angular 4......我在那里使用TypeScript。总有一天,我会停止错误地将较新版本的AngularJS称为AngularJS。
我的挑战是,似乎异步方法只能由其他异步方法一直调用
调用堆栈。
这并不完全正确。可以在同步方法中使用异步方法。当然,您正在失去大部分"异步"效果,但有时您必须这样做。当异步方法还原任务时,您有一些选择。
当 Task 返回结果时,任何对t.Result
的引用都将阻止执行,直到已知为止。另一种选择是使用 Task.Wait(最好是超时)。例如,验证谷歌 jwt 令牌的代码:
public bool ValidateGoogleToken(string token)
{
try
{
if(GoogleJsonWebSignature.ValidateAsync(token).Wait(1000))
return true; //success
//timeout exceeded
}
catch (Exception e)
{
//tampered token
}
return false;
}