重定向授权页面时出现错误 400:invalid_request
Getting Error 400: invalid_request while redirecting Authorization page
遵循本指南(https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-asp.net-mvc) I made the code work in localhost but it gives an Error 400: invalid_request device_id and device_name are required for private IP: http://xx.xx.xx.xx:xxxxx/AuthCallback/IndexAsync,同时重定向到授权页面。我们在 dns 中为我们的 windows 服务器 ip 地址添加了子域,并在 google api console. 为什么 google 获取服务器的 ip 地址而不是子域?问题与 dns 有关吗?
这些是本地机器上的工作代码:
HomeController.cs
public class HomeController : Controller
{
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
AuthorizeAsync(cancellationToken);
if (result.Credential != null)
{
var service = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "BPM Mail"
});
var gmailProfile = service.Users.GetProfile("me").Execute();
var userGmailEmail = gmailProfile.EmailAddress;
Utils.userMail = userGmailEmail;
Utils.cred = result.Credential;
// SAMPLE CODE:
//var list = await service.Files.List().ExecuteAsync();
//ViewBag.Message = "FILE COUNT IS: " + list.Items.Count();
return new RedirectResult("~/Apps/Mail/Default.aspx");
}
else
{
return new RedirectResult(result.RedirectUri);
}
}
}
AppFlowMetadata.cs
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "ClientId ",
ClientSecret = "ClientSecret "
},
Scopes = new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify },
DataStore = new FileDataStore("D:/bpm_mail/mytokens/token.json", true)
});
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["user"];
//Utils.userId = user.ToString();
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
//public override string AuthCallback
//{
// get { return @"/AuthCallback/IndexAsync"; }
//}
}
AuthCallbackController.cs
public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
{
protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData
{
get { return new AppFlowMetadata(); }
}
}
通过将私有 ip 更改为 public 并将其重定向到域来解决问题。
遵循本指南(https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-asp.net-mvc) I made the code work in localhost but it gives an Error 400: invalid_request device_id and device_name are required for private IP: http://xx.xx.xx.xx:xxxxx/AuthCallback/IndexAsync,同时重定向到授权页面。我们在 dns 中为我们的 windows 服务器 ip 地址添加了子域,并在 google api console. 为什么 google 获取服务器的 ip 地址而不是子域?问题与 dns 有关吗? 这些是本地机器上的工作代码: HomeController.cs
public class HomeController : Controller
{
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
AuthorizeAsync(cancellationToken);
if (result.Credential != null)
{
var service = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "BPM Mail"
});
var gmailProfile = service.Users.GetProfile("me").Execute();
var userGmailEmail = gmailProfile.EmailAddress;
Utils.userMail = userGmailEmail;
Utils.cred = result.Credential;
// SAMPLE CODE:
//var list = await service.Files.List().ExecuteAsync();
//ViewBag.Message = "FILE COUNT IS: " + list.Items.Count();
return new RedirectResult("~/Apps/Mail/Default.aspx");
}
else
{
return new RedirectResult(result.RedirectUri);
}
}
}
AppFlowMetadata.cs
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "ClientId ",
ClientSecret = "ClientSecret "
},
Scopes = new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify },
DataStore = new FileDataStore("D:/bpm_mail/mytokens/token.json", true)
});
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["user"];
//Utils.userId = user.ToString();
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
//public override string AuthCallback
//{
// get { return @"/AuthCallback/IndexAsync"; }
//}
}
AuthCallbackController.cs
public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
{
protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData
{
get { return new AppFlowMetadata(); }
}
}
通过将私有 ip 更改为 public 并将其重定向到域来解决问题。