我们有一个 Microsoft Teams 消息扩展项目,其中包含用于登录的自定义命令:
"commands": [
{
"id": "SIGNIN",
"type": "action",
"title": "Sign In",
"description": "sign into our application",
"initialRun": false,
"fetchTask": true,
"context": [
"commandBox",
"compose",
"message"
],
"parameters": [
{
"name": "param",
"title": "param",
"description": ""
}
]
}
]
单击后,我们将从 Teams 打开应用程序并提示登录:
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
var state = action.State; // Check the state value
if (state != null)
{
var UserToken = JsonConvert.DeserializeObject<UserToken>(state);
}
// Handle different actions using switch.
switch (action.CommandId)
{
case "SIGNIN":
var output = new MessagingExtensionActionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = "auth",
SuggestedActions = new MessagingExtensionSuggestedAction
{
Actions = new List<CardAction>
{
new CardAction
{
Type = ActionTypes.OpenUrl,
Value = "https://localhost:44302/Account/Login?loginfromteams=true",
Text = "Please sign in",
Title = "Sign in",
},
},
},
},
};
return await Task.FromResult(output);
}
}
成功登录我们的应用程序后,我们将包含访问令牌和刷新令牌的响应发送回 Teams:
<script>
document.onreadystatechange = function () {
microsoftTeams.app.initialize().then(function () {
microsoftTeams.authentication.notifySuccess(JSON.stringify({
accessToken: "@Model.AccessToken",
refreshToken: "@Model.RefreshToken",
}));
});
};
</script>
Teams 在上面显示的
action.State
方法的 OnTeamsMessagingExtensionFetchTaskAsync
参数中接收此信息:
var state = action.State; // Check the state value
if (state != null)
{
var UserToken = JsonConvert.DeserializeObject<UserToken>(state);
UserToken.AccessToken // access token from our application available here
UserToken.RefreshToken // refresh token from our application available here
}
现在我们有了一个令牌,我们希望将其存储在用户团队会话中,这样他们就不必在每次需要调用我们的 api 时登录我们的应用程序。我们希望它在应用程序中持续存在,以便当应用程序重新启动时,访问令牌仍然可用于将来的 api 调用。
我们看不到一种明确的方法来存储令牌,无论是在 HTTP 上下文中还是在本地存储中。建议的前进方向是什么?
从应用程序收到访问令牌和刷新令牌后,您可以使用 UserToken 属性将访问令牌存储在用户的 Teams 会话中。您可以使用 ITurnContext 对象来访问 UserToken 属性。
var userToken = new UserToken
{
AccessToken = "<access token>",
RefreshToken = "<refresh token>"
};
await turnContext.TurnState.Get<IUserTokenProvider>
().SaveTokenAsync(turnContext, "<connection name>", "<user id>", userToken, cancellationToken);
要检索访问令牌以供将来的 API 调用,您可以再次使用 UserToken 属性。
var userToken = await turnContext.TurnState.Get<IUserTokenProvider>
().GetTokenAsync(turnContext, "<connection name>", "<user id>",
cancellationToken);
if (userToken != null)
{
var accessToken = userToken.AccessToken;
// Use the access token for API calls
}