Box API在获取访问令牌时始终返回无效的grant_type参数 [英] Box API always returns invalid grant_type parameter on obtaining access token

查看:168
本文介绍了Box API在获取访问令牌时始终返回无效的grant_type参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为WP8编写自己的Box SDK,以充分利用任务。我在获取访问令牌时遇到问题。我总是以此作为回报:

  { error: invalid_request, error_description:无效的grant_type参数或参数丢失} 

我正在使用的代码(全部在C#中)是:

 内部常量String TokenURL = https://api.box.com/oauth2/token; 

CloudHttpAsync.DownloadResponceStreamAsync

CloudHttpAsync.PostAsync

TokenURL,
新的MemoryStream

UTF8Encoding .UTF8.GetBytes

HttpUtility.UrlEncode

String.Format

grant_type = authorization_code& code = {0}& client_id = {1}& client_secret = {2}& redirect_uri = {3},
代码,
ClientID,
ClientSecret,
RedirectURI



),
空,

),

).ContinueWith((AsyncStream)=>
{
尝试
{
if(AsyncStream.Exception!= null)
{
TaskSource.Try SetException(AsyncStream.Exception.InnerExceptions);
的回报;
}

字符串结果=;
使用(StreamReader Reader = new StreamReader(AsyncStream.Result))
{
Result = Reader.ReadToEnd();
}

BoxAuthToken令牌= JsonConvert.DeserializeObject< BoxAuthToken>(结果);
TaskSource.TrySetResult(Token);
}
catch(异常e)
{
TaskSource.TrySetException(e);
}
});

  public static Task< HttpWebResponse> PostAsync(字符串URL,流UploadData,IRequestSigner签名者,IProgress< NetworkProgress>进度)
{
TaskCompletionSource< HttpWebResponse> TaskSource = new TaskCompletionSource< HttpWebResponse>();

HttpWebRequest请求= WebRequest.CreateHttp(URL);
Request.Method = POST;

if(Signer!= null)
{
Signer.Sign(Request).ContinueWith((o)=>
{
if( o.Exception!= null)
{
TaskSource.TrySetException(o.Exception.InnerExceptions);
return;
}

UploadDataAsync(Request, UploadData,Progress).ContinueWith(((AsyncRequest)=>
{
if(AsyncRequest.Exception!= null)
{
TaskSource.TrySetException(AsyncRequest.Exception.InnerExceptions) ;
return;
}

GetResponceAsync(Request).ContinueWith((AsyncResponce)=>
{
if(AsyncResponce.Exception!= null )
{
TaskSource.TrySetException(Asy ncResponce.Exception.InnerExceptions);
的回报;
}

TaskSource.TrySetResult(AsyncResponce.Result);
});
});
});
}
else
{
UploadDataAsync(Request,UploadData,Progress).ContinueWith((AsyncRequest)=>
{
if(AsyncRequest.Exception != null)
{
TaskSource.TrySetException(AsyncRequest.Exception.InnerExceptions);
return;
}

GetResponceAsync(Request).ContinueWith( (AsyncResponce)=>
{
如果(AsyncResponce.Exception!= null)
{
TaskSource.TrySetException(AsyncResponce.Exception.InnerExceptions);
返回;
}

TaskSource.TrySetResult(AsyncResponce.Result);
});
});
}

返回TaskSource.Task;
}

内部静态Task< HttpWebRequest> UploadDataAsync(HttpWebRequest Request,Stream Data,IProgress< NetworkProgress> Progress)
{
TaskCompletionSource< HttpWebRequest> TaskSource = new TaskCompletionSource< HttpWebRequest>();

如果(Data.Length!= 0)
{
Request.ContentLength = Data.Length;
Request.AllowWriteStreamBuffering = false;

Request.BeginGetRequestStream(new AsyncCallback((IAR)=>
{
try
{
using(Stream UploadStream = Request.EndGetRequestStream(IAR ))
{
Int64上传= 0;
Int64 TotalUploaded = 0;
Int64 Total = Data.Length;
Byte [] Buffer = new Byte [4096] ;

而(TotalUploaded< Total)
{
Upload = Data.Read(Buffer,0,Buffer.Length);
TotalUploaded + = Upload;
UploadStream.Write(Buffer,0,(Int32)Upload);

if(进度!= null)
{
P rogress.Report(new NetworkProgress()
{
Operation = NetworkOperation.Uploading,
TotalBytes =总计,
BytesProcessed = TotalUploaded
});
}
}
}

TaskSource.TrySetResult(Request);
}
catch(异常e)
{
TaskSource.TrySetException(e);
}
}),
null);
}
其他
{
TaskSource.TrySetResult(Request);
}

返回TaskSource.Task;
}

内部静态Task< HttpWebResponse> GetResponceAsync(HttpWebRequest Request)
{
TaskCompletionSource< HttpWebResponse> TaskSource = new TaskCompletionSource< HttpWebResponse>();

Request.BeginGetResponse(new AsyncCallback((IAR)=>
{
try
{
HttpWebResponse Responce =(HttpWebResponse)Request.EndGetResponse( IAR);
TaskSource.TrySetResult(Responce);
}
catch(Exception e)
{
if(e is WebException&&(e as WebException ).Response.ContentLength> 0)
{
TaskSource.TrySetResult((HttpWebResponse)(e as WebException).Response);
}
else
{
TaskSource.TrySetException(e);
}
}
}),
null);

返回TaskSource.Task;
}

public static Task< StreamAndLength> GetResponceStreamAsync(Task< HttpWebResponse> Task)
{
TaskCompletionSource< StreamAndLength> TaskSource = new TaskCompletionSource< StreamAndLength>();

Task.ContinueWith((AsyncHWR)=>
{
if(AsyncHWR.Exception!= null)
{
TaskSource.TrySetException(AsyncHWR .Exception.InnerExceptions);
return;
}

HttpWebResponse Response = AsyncHWR.Result;
TaskSource.TrySetResult(new StreamAndLength(){Stream = Responce.GetResponseStream (),长度= Responce.ContentLength});
});

返回TaskSource.Task;
}

public static Task< MemoryStream> DownloadResponceStreamAsync(Task< HttpWebResponse> Task,IProgress< NetworkProgress> Progress)
{
TaskCompletionSource< MemoryStream> TaskSource = new TaskCompletionSource< MemoryStream>();

GetResponceStreamAsync(Task).ContinueWith((AsyncStream)=>
{
if(AsyncStream.Exception!= null)
{
TaskSource。 TrySetException(AsyncStream.Exception.InnerExceptions);
返回;
}

MemoryStream MemStream = new MemoryStream();
MemStream.SetLength(AsyncStream.Result.Length) ;

Int64 CurrentRead = 0;
Int64 TotalRead = 0;
Int64 Total = AsyncStream.Result.Length;
Byte [] Buffer = new Byte [4096] ;

使用(Stream DownloadStream = AsyncStream.Result.Stream)
而(TotalRead< Total)
{
CurrentRead = DownloadStream.Read(Buffer,0, Buffer.Length);
MemStream.Write(Buffer,0,(Int32)CurrentRead);
TotalRead + = CurrentRead;

if(Progress!= null)
{
Progress.Report(new NetworkProgress()
{
Operation = NetworkOperation.Downloading,
TotalBytes =总计,
BytesProcessed = TotalRead
});
}
}

MemStream.Position = 0;
TaskSource.TrySetResult(MemStream);
});

返回TaskSource.Task;
}

内部类StreamAndLength
{
public Stream Stream {get;组; }
public Int64 Length {get;组; }
}

对不起,有很多代码,我喜欢写一般:)



编辑:原始响应(已删除ClientID和客户端机密)



URL编码每个值时:

  POST https://api.box.com/oauth2/token HTTP / 1.1 
接受:* / *
内容长度:196
接受编码:身份
用户代理:NativeHost
主机:api.box.com
连接:保持活动
缓存-控制:无缓存

grant_type = authorization_code& code = JknaLbfT6lAXmey3FLYrp9eg1jMbpFuQ& client_id = [subbed]& client_secret = [subbed]& redirect_uri = https%3a%2f%2fbbBox

返回:

  HTTP / 1.1 400错误的请求
服务器:nginx
日期:2013年3月1日星期五07:35:22 GMT
内容类型:application / json
连接:keep-alive
Set-Cookie:box_visitor_id = 51305a3a187f34.52738262; expires =星期六,2014年3月1日07:35:22 GMT;路径= /; domain = .box.com
Set-Cookie:country_code = US; expires = Tue,30-Apr-2013 07:35:22 GMT; path = /
缓存控制:无存储
内容长度:99

{ error: invalid_request, error_description:无效的grant_type参数或参数丢失}

URL编码整个字符串时:

  POST https://api.box.com/oauth2/token HTTP / 1.1 
接受:* / *
内容长度:214
接受编码:身份
用户代理:NativeHost
主机:api.box.com
连接:保持活动
缓存控制:无缓存

grant_type%3dauthorization_code%26code%3d3ikruv5elfdw3fOP55aMDSX7ybLqBFlA%26client_id%3d [subbed]%26client_secret%3d [subbed]%26redirect_uri%3dhttps%3a%2f%2fCloudBox
> p $ p>

返回

  HTTP / 1.1 400错误请求
服务器:nginx
日期:2013年3月1日星期五,格林尼治标准时间
内容类型:application / json
连接:keep-alive
设置Cookie:box_visitor_id = 51305cbb339de4.03221876; expires =星期六,2014年3月1日07:46:03 GMT;路径= /; domain = .box.com
Set-Cookie:country_code = US; expires = Tue,30-Apr-2013 07:46:03 GMT; path = /
缓存控制:无存储
内容长度:99

{ error: invalid_request, error_description:无效的grant_type参数或参数缺少}

没有URL编码:

  POST https://api.box.com/oauth2/token HTTP / 1.1 
接受:* / *
内容长度:190
接受-编码:身份
用户代理:NativeHost
主机:api.box.com
连接:保持活动
缓存控制:无缓存

grant_type = authorization_code& code = 2wgIzfqhvIgRtVIp2ZvqZ9X8R5u0QNaf& client_id = [subbed]& client_secret = [subbed]& redirect_uri = https:// CloudBoxWP8
$$$

返回:

  HTTP / 1.1 400错误请求
服务器:nginx
日期:2013年3月1日星期五,格林尼治标准时间
内容类型:application / json
连接:keep-alive
Set-Cookie:box_visitor_id = 51305dc751d7f5.67064854; expires =星期六,2014年3月1日07:50:31 GMT;路径= /; domain = .box.com
Set-Cookie:country_code = US; expires = Tue,30-Apr-2013 07:50:31 GMT; path = /
缓存控制:无存储
内容长度:99

{ error: invalid_request, error_description:无效的grant_type参数或参数缺少}


解决方案

Box API上未列出任何内容文档,但要获取访问令牌的请求需要标头 Content-Type:application / x-www-form-urlencoded



我在这部分上也停留了一段时间,直到在StackOverflow上找到答案为止。我忘记了它的链接。


I'm writing my own Box SDK for WP8 to make the most out of Tasks. I am having trouble obtaining an access token. I always get this as a return:

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

The code (all in C#) I'm using is:

    internal const String TokenURL = "https://api.box.com/oauth2/token";

CloudHttpAsync.DownloadResponceStreamAsync
(
    CloudHttpAsync.PostAsync
    (
        TokenURL,
        new MemoryStream
        (
            UTF8Encoding.UTF8.GetBytes
            (
                HttpUtility.UrlEncode
                (
                    String.Format
                    (
                        "grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&redirect_uri={3}",
                        Code,
                        ClientID,
                        ClientSecret,
                        RedirectURI
                    )
                )
            )
        ),
        null,
        null
    ),
    null
).ContinueWith((AsyncStream) =>
    {
        try
        {
            if (AsyncStream.Exception != null)
            {
                TaskSource.TrySetException(AsyncStream.Exception.InnerExceptions);
                return;
            }

            String Result = "";
            using (StreamReader Reader = new StreamReader(AsyncStream.Result))
            {
                Result = Reader.ReadToEnd();
            }

            BoxAuthToken Token = JsonConvert.DeserializeObject<BoxAuthToken>(Result);
            TaskSource.TrySetResult(Token);
        }
        catch (Exception e)
        {
            TaskSource.TrySetException(e);
        }
    });

and

    public static Task<HttpWebResponse> PostAsync(String URL, Stream UploadData, IRequestSigner Signer, IProgress<NetworkProgress> Progress)
    {
        TaskCompletionSource<HttpWebResponse> TaskSource = new TaskCompletionSource<HttpWebResponse>();

        HttpWebRequest Request = WebRequest.CreateHttp(URL);
        Request.Method = "POST";

        if (Signer != null)
        {
            Signer.Sign(Request).ContinueWith((o) =>
            {
                if (o.Exception != null)
                {
                    TaskSource.TrySetException(o.Exception.InnerExceptions);
                    return;
                }

                UploadDataAsync(Request, UploadData, Progress).ContinueWith((AsyncRequest) =>
                {
                    if (AsyncRequest.Exception != null)
                    {
                        TaskSource.TrySetException(AsyncRequest.Exception.InnerExceptions);
                        return;
                    }

                    GetResponceAsync(Request).ContinueWith((AsyncResponce) =>
                    {
                        if (AsyncResponce.Exception != null)
                        {
                            TaskSource.TrySetException(AsyncResponce.Exception.InnerExceptions);
                            return;
                        }

                        TaskSource.TrySetResult(AsyncResponce.Result);
                    });
                });
            });
        }
        else
        {
            UploadDataAsync(Request, UploadData, Progress).ContinueWith((AsyncRequest) =>
            {
                if (AsyncRequest.Exception != null)
                {
                    TaskSource.TrySetException(AsyncRequest.Exception.InnerExceptions);
                    return;
                }

                GetResponceAsync(Request).ContinueWith((AsyncResponce) =>
                {
                    if (AsyncResponce.Exception != null)
                    {
                        TaskSource.TrySetException(AsyncResponce.Exception.InnerExceptions);
                        return;
                    }

                    TaskSource.TrySetResult(AsyncResponce.Result);
                });
            });
        }

        return TaskSource.Task;
    }

    internal static Task<HttpWebRequest> UploadDataAsync(HttpWebRequest Request, Stream Data, IProgress<NetworkProgress> Progress)
    {
        TaskCompletionSource<HttpWebRequest> TaskSource = new TaskCompletionSource<HttpWebRequest>();

        if (Data.Length != 0)
        {
            Request.ContentLength = Data.Length;
            Request.AllowWriteStreamBuffering = false;

            Request.BeginGetRequestStream(new AsyncCallback((IAR) =>
                {
                    try
                    {
                        using (Stream UploadStream = Request.EndGetRequestStream(IAR))
                        {
                            Int64 Upload = 0;
                            Int64 TotalUploaded = 0;
                            Int64 Total = Data.Length;
                            Byte[] Buffer = new Byte[4096];

                            while (TotalUploaded < Total)
                            {
                                Upload = Data.Read(Buffer, 0, Buffer.Length);
                                TotalUploaded += Upload;
                                UploadStream.Write(Buffer, 0, (Int32)Upload);

                                if (Progress != null)
                                {
                                    Progress.Report(new NetworkProgress()
                                    {
                                        Operation = NetworkOperation.Uploading,
                                        TotalBytes = Total,
                                        BytesProcessed = TotalUploaded
                                    });
                                }
                            }
                        }

                        TaskSource.TrySetResult(Request);
                    }
                    catch (Exception e)
                    {
                        TaskSource.TrySetException(e);
                    }
                }),
                null);
        }
        else
        {
            TaskSource.TrySetResult(Request);
        }

        return TaskSource.Task;
    }

    internal static Task<HttpWebResponse> GetResponceAsync(HttpWebRequest Request)
    {
        TaskCompletionSource<HttpWebResponse> TaskSource = new TaskCompletionSource<HttpWebResponse>();

        Request.BeginGetResponse(new AsyncCallback((IAR) =>
            {
                try
                {
                    HttpWebResponse Responce = (HttpWebResponse)Request.EndGetResponse(IAR);
                    TaskSource.TrySetResult(Responce);
                }
                catch (Exception e)
                {
                    if (e is WebException && (e as WebException).Response.ContentLength > 0)
                    {
                        TaskSource.TrySetResult((HttpWebResponse)(e as WebException).Response);
                    }
                    else
                    {
                        TaskSource.TrySetException(e);
                    }
                }
            }),
            null);

        return TaskSource.Task;
    }

    public static Task<StreamAndLength> GetResponceStreamAsync(Task<HttpWebResponse> Task)
    {
        TaskCompletionSource<StreamAndLength> TaskSource = new TaskCompletionSource<StreamAndLength>();

        Task.ContinueWith((AsyncHWR) =>
            {
                if (AsyncHWR.Exception != null)
                {
                    TaskSource.TrySetException(AsyncHWR.Exception.InnerExceptions);
                    return;
                }

                HttpWebResponse Responce = AsyncHWR.Result;
                TaskSource.TrySetResult( new StreamAndLength() { Stream = Responce.GetResponseStream(), Length = Responce.ContentLength });
            });

        return TaskSource.Task;
    }

    public static Task<MemoryStream> DownloadResponceStreamAsync(Task<HttpWebResponse> Task, IProgress<NetworkProgress> Progress)
    {
        TaskCompletionSource<MemoryStream> TaskSource = new TaskCompletionSource<MemoryStream>();

        GetResponceStreamAsync(Task).ContinueWith((AsyncStream) =>
            {
                if (AsyncStream.Exception != null)
                {
                    TaskSource.TrySetException(AsyncStream.Exception.InnerExceptions);
                    return;
                }

                MemoryStream MemStream = new MemoryStream();
                MemStream.SetLength(AsyncStream.Result.Length);

                Int64 CurrentRead = 0;
                Int64 TotalRead = 0;
                Int64 Total = AsyncStream.Result.Length;
                Byte[] Buffer = new Byte[4096];

                using (Stream DownloadStream = AsyncStream.Result.Stream)
                while (TotalRead < Total)
                {
                    CurrentRead = DownloadStream.Read(Buffer, 0, Buffer.Length);
                    MemStream.Write(Buffer, 0, (Int32)CurrentRead);
                    TotalRead += CurrentRead;

                    if (Progress != null)
                    {
                        Progress.Report(new NetworkProgress()
                        {
                            Operation = NetworkOperation.Downloading,
                            TotalBytes = Total,
                            BytesProcessed = TotalRead
                        });
                    }
                }

                MemStream.Position = 0;
                TaskSource.TrySetResult(MemStream);
            });

        return TaskSource.Task;
    }

    internal class StreamAndLength
    {
        public Stream Stream { get; set; }
        public Int64 Length { get; set; }
    }

Sorry there is a lot of code, I like to write generically :)

Edit: Raw Responces (ClientID & Client Secret removed)

When URL encoding each value:

POST https://api.box.com/oauth2/token HTTP/1.1
Accept: */*
Content-Length: 196
Accept-Encoding: identity
User-Agent: NativeHost
Host: api.box.com
Connection: Keep-Alive
Cache-Control: no-cache

grant_type=authorization_code&code=JknaLbfT6lAXmey3FLYrp9eg1jMbpFuQ&client_id=[subbed]&client_secret=[subbed]&redirect_uri=https%3a%2f%2fCloudBoxWP8

Return:

HTTP/1.1 400 Bad Request
Server: nginx
Date: Fri, 01 Mar 2013 07:35:22 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=51305a3a187f34.52738262; expires=Sat, 01-Mar-2014 07:35:22 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Tue, 30-Apr-2013 07:35:22 GMT; path=/
Cache-Control: no-store
Content-Length: 99

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

When URL encode the entire string:

POST https://api.box.com/oauth2/token HTTP/1.1
Accept: */*
Content-Length: 214
Accept-Encoding: identity
User-Agent: NativeHost
Host: api.box.com
Connection: Keep-Alive
Cache-Control: no-cache

grant_type%3dauthorization_code%26code%3d3ikruv5elfdw3fOP55aMDSX7ybLqBFlA%26client_id%3d[subbed]%26client_secret%3d[subbed]%26redirect_uri%3dhttps%3a%2f%2fCloudBoxWP8

Return

HTTP/1.1 400 Bad Request
Server: nginx
Date: Fri, 01 Mar 2013 07:46:03 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=51305cbb339de4.03221876; expires=Sat, 01-Mar-2014 07:46:03 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Tue, 30-Apr-2013 07:46:03 GMT; path=/
Cache-Control: no-store
Content-Length: 99

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

No URL encoding:

POST https://api.box.com/oauth2/token HTTP/1.1
Accept: */*
Content-Length: 190
Accept-Encoding: identity
User-Agent: NativeHost
Host: api.box.com
Connection: Keep-Alive
Cache-Control: no-cache

grant_type=authorization_code&code=2wgIzfqhvIgRtVIp2ZvqZ9X8R5u0QNaf&client_id=[subbed]&client_secret=[subbed]&redirect_uri=https://CloudBoxWP8

Return:

HTTP/1.1 400 Bad Request
Server: nginx
Date: Fri, 01 Mar 2013 07:50:31 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=51305dc751d7f5.67064854; expires=Sat, 01-Mar-2014 07:50:31 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Tue, 30-Apr-2013 07:50:31 GMT; path=/
Cache-Control: no-store
Content-Length: 99

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

解决方案

It's not listed anywhere on the Box API documentation, but the request for retrieving the access token requires the header Content-Type: application/x-www-form-urlencoded

I was also stuck on this part for a while until I found the answer on StackOverflow. I forget the link to it though.

这篇关于Box API在获取访问令牌时始终返回无效的grant_type参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆