【问题标题】:How to fix "Bad request" error when sending Rest request to Google Oauth2 SSO in HttpClient如何在 HttpClient 中向 Google Oauth2 SSO 发送 Rest 请求时修复“错误请求”错误
【发布时间】:2019-08-19 02:49:12
【问题描述】:

我正在尝试学习如何实现 Google 的 Oauth2 SSO 登录功能。到目前为止,我已经到了一切正常的地步,除非我尝试使用 C# 中的 REST 向“https://accounts.google.com/o/oauth2/token”发送请求以获取 Access_code/Token。我已经在 google 上注册了我的本地主机和相应的端口,并且我设法让我的 POST 请求在 POSTMAN 中工作,但是当我尝试在 C# 中发送请求时,我的 HttpRequestMessage 返回 400 错误请求。

首先,我有一个 Authorization.aspx 页面,该页面运行一个命令,该命令将用户重定向到用户登录的 google 授权页面,然后重定向到我的页面 http://localhost:64716/GoogleCallBack.aspx 获取响应。在页面中,它获取授权码并尝试向基本 URL 发送 POST 请求。我试过在它工作的 POSTMAN 中运行它(尽管只有一个新的授权码)。所以我知道问题出在我的 C# 代码上。我尝试过使用 webrequest,也尝试过将媒体类型更改为 application/Json 和 application/x-www-form-urlencoded

    protected void Page_Load(object sender, EventArgs e)
    {

        string Error = Request.QueryString["error"];

        string Code = Request.QueryString["code"];
        if (Error != null) { }
        else if (Code != null)
        {

            string UserId = Request.QueryString["state"];
            int Id = Convert.ToInt32(UserId);
            string AccessToken = string.Empty;
            string RefreshToken = ExchangeAuthorizationCode(Id, Code, out AccessToken);
            string Url = "Authorize.aspx?UserId=" + UserId;
            Response.Redirect(Url, true);
        }
    }
    private string ExchangeAuthorizationCode(int userId, string code, out string accessToken)
    {
        string baseurl = "https://accounts.google.com/o/oauth2/token";
        accessToken = string.Empty;
        string ClientSecret = ConfigurationManager.AppSettings["ClientSecrete"];
        string ClientId = ConfigurationManager.AppSettings["ClientId"];

        string RedirectUrl = "http://localhost:64716/GoogleCallBack.aspx";

        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(baseurl);
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/Json"));

            var nvc = new List<KeyValuePair<string, string>>();
            nvc.Add(new KeyValuePair<string, string>("Code", code));
            nvc.Add(new KeyValuePair<string, string>("Client_id", ClientId));
            nvc.Add(new KeyValuePair<string, string>("Client_secret", ClientSecret));
            nvc.Add(new KeyValuePair<string, string>("Redirect_uri", RedirectUrl));
            nvc.Add(new KeyValuePair<string, string>("Grant_type", "authorization_code"));
            nvc.Add(new KeyValuePair<string, string>("access_type", "offline"));

            var req = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress) { Content = new FormUrlEncodedContent(nvc) };
            var resres = client.SendAsync(req).Result;

            return "temp";

        }

    }

我希望我的响应是状态码 200,带有来自 google 的 access_token(就像在 Postman 中一样)

【问题讨论】:

  • 我没有看到 oauth 令牌试图像这样发送。你的标题与邮递员的匹配吗?
  • 在这个特定的示例中,不,在 Postman 中,我使用 application/x-www-form-urlencoded 而不是 application/json,但我也尝试过添加它。它没有解决我的问题。

标签: c# asp.net rest oauth-2.0


【解决方案1】:

[已解决]这就是我所做的(在几个朋友的帮助下)

  1. 将标头更改为 JSON

  2. 将基本 URI 移至 PostAsync()

  3. 一旦我更改了所有内容,我可以看到错误出现在 redirect_Uri 中,然后我将其更改为与邮递员中的匹配。现在它可以工作了

    protected void Page_Load(object sender, EventArgs e)
        {
            //you will get this, when any error will occur while authorization otherwise null    
            string Error = Request.QueryString["error"];
            //authorization code after successful authorization    
            string Code = Request.QueryString["code"];
            if (Error != null) { }
            else if (Code != null)
            {
                //Remember, we have set userid in State    
                string UserId = Request.QueryString["state"];
                //Get AccessToken    
                int Id = Convert.ToInt32(UserId);
                string AccessToken = string.Empty;
                string RefreshToken = ExchangeAuthorizationCode(Id, Code, out AccessToken);
                //saving refresh token in database    
                SaveRefreshToken(Id, RefreshToken);
                //Get Email Id of the authorized user    
                string EmailId = FetchEmailId(AccessToken);
                //Saving Email Id    
                SaveEmailId(UserId, EmailId);
                //Redirect the user to Authorize.aspx with user id    
                string Url = "Authorize.aspx?UserId=" + UserId;
                Response.Redirect(Url, true);
            }
        }
    
        private string ExchangeAuthorizationCode(int userId, string code, out string accessToken)
        {
            string baseurl = "https://accounts.google.com/o/oauth2/token";
            accessToken = string.Empty;
            string ClientSecret = ConfigurationManager.AppSettings["ClientSecrete"];
            string ClientId = ConfigurationManager.AppSettings["ClientId"];
            // //get this value by opening your web app in browser.    
            string RedirectUrl = "http://localhost:64716/GoogleCallback.aspx"; //I changed this to match the one in Postman
    
            using (var client = new HttpClient())
            {
                //client.BaseAddress = new Uri("https://accounts.google.com/o/oauth2"); //I replaced the Uri to "var result = client.PostAsync("https://accounts.google.com/o/oauth2/token", nvc).Result;"
                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // I made this JSON
                // I removed this "client.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");"
    
                var nvc = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string, string>("grant_type", "authorization_code"),
                new KeyValuePair<string, string>("code", code),
                new KeyValuePair<string, string>("client_id", ClientId),
                new KeyValuePair<string, string>("client_secret", ClientSecret),
                new KeyValuePair<string, string>("redirect_uri", RedirectUrl),
                new KeyValuePair<string, string>("access_type", "offline")
                });
    
                var result = client.PostAsync("https://accounts.google.com/o/oauth2/token", nvc).Result;
    
                var resultContent = result.Content.ReadAsStringAsync();
    
                var tokenResponse = JsonConvert.DeserializeObject<Authorization_request_body>(resultContent.ToString());
    
                return "temp";
    
                }
    
            }
    

【讨论】:

    猜你喜欢
    • 2015-11-03
    • 2021-01-14
    • 2020-08-22
    • 2019-12-13
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多