注意:使用登录按钮是不是一个选项
一年前,我在创造时刻方面遇到了困难。那时我使用的是Google+ API . net客户端1.2版本。正如我在这篇文章中所描述的,我让它工作,尽管代码不能不时插入一个时刻。我希望这个过程现在更稳定,更容易实现,看起来就像你可以在这里下载的例子中看到的那样——写这篇文章时的当前版本是v1.8。因此,我按照下载中的SimpleOAuth2
示例创建了一个简单的项目,但实现了Google+。这是我找到的代码:
public partial class _Default : System.Web.UI.Page
{
private PlusService service;
// Application logic should manage users authentication.
// This sample works with only one user. You can change
// it by retrieving data from the session.
private const string UserId = "user-id";
protected void Page_Load(object sender, EventArgs e)
{
GoogleAuthorizationCodeFlow flow;
var assembly = Assembly.GetExecutingAssembly();
using (var stream = assembly.GetManifestResourceStream(
"GPlusSample.client_secrets.json"))
{
flow = new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("GPlusSample.Store"),
ClientSecretsStream = stream,
//
// Tried only this scope but it did not work
//Scopes = new[] { PlusService.Scope.PlusMe }
//
// I tried the following: but did not work either
//Scopes = new[] { PlusService.Scope.PlusMe,
// "https://www.googleapis.com/auth/plus.moments.write" }
//
// I tried this as well and it failed
//Scopes = new[] { PlusService.Scope.PlusLogin }
//
// Maybe this... but still no joy
Scopes = new[] { PlusService.Scope.PlusLogin,
PlusService.Scope.PlusMe }
});
}
var uri = Request.Url.ToString();
var code = Request["code"];
if (code != null)
{
var token = flow.ExchangeCodeForTokenAsync(UserId, code,
uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;
// Extract the right state.
var oauthState = AuthWebUtility.ExtracRedirectFromState(
flow.DataStore, UserId, Request["state"]).Result;
Response.Redirect(oauthState);
}
else
{
var result = new AuthorizationCodeWebApp(flow, uri, uri)
.AuthorizeAsync(UserId, CancellationToken.None).Result;
if (result.RedirectUri != null)
{
// Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri);
}
else
{
// The data store contains the user credential,
// so the user has been already authenticated.
service = new PlusService(new BaseClientService.Initializer
{
ApplicationName = "Plus API Sample",
HttpClientInitializer = result.Credential
});
}
}
}
/// <summary>Gets the TasksLists of the user.</summary>
public async System.Threading.Tasks.Task InsertMoment()
{
try
{
var me = service.People.Get("me").Execute();
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Id=Guid.NewGuid().ToString(),
Image="http://www.google.com/s2/static/images/GoogleyEyes.png",
Type="",
Name = "test message",
Description="test",
Text="test message",
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
output.Text = "<h1>" + response.Id + "</h1>";
}
catch (Exception ex)
{
var str = ex.ToString();
str = str.Replace(Environment.NewLine, Environment.NewLine + "<br/>");
str = str.Replace(" ", " ");
output.Text = string.Format("<font color="red">{0}</font>", str);
}
}
protected async void createMomentButton_Click(object sender, EventArgs e)
{
await InsertMoment();
}
}
该代码总是给我一个401未经授权的错误,即使我有Google+ API 打开为我的项目。下面是我得到的实际错误:
service plus抛出了一个异常:Google。GoogleApiException:google . api . requests . requesterror Unauthorized [401] Errors [消息[未经授权]位置[-]原因[未经授权]域[global]]
有趣的是,插入时刻失败了,即使调用People.Get("me")有效——get("me")适用于我上面列出的所有作用域组合。值得注意的是,每次我尝试一个新的作用域时,我首先注销我的Google帐户,并删除存储在GPlusSample.Store
中的访问令牌。
编辑
我试着设置只是Url,而不是由伊恩建议的个别项目,我得到了完全相同的错误。
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Url = "https://developers.google.com/+/web/snippet/examples/thing"
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
https://www.googleapis.com/auth/plus.login是编写时刻的正确范围,但您还需要请求您想要编写的特定应用程序活动类型。它的参数是request_visible_actions,它接受一个空格分隔的类型参数列表(列在https://developers.google.com/+/api/moment-types/上-例如http://schemas.google.com/AddActivity)。
客户端库可能没有添加request_visible_actions的方法,所以你可能不得不将它添加到你手动重定向用户到的auth URL上(记住URLencode应用程序活动类型URL !)