.net – 通过OAuth访问imgUr(上传到用户帐户)

.net – 通过OAuth访问imgUr(上传到用户帐户),第1张

概述为了开始执行这个“简单”的任务,我已经研究了一个程序,我已经将其作为示例 here来跟踪并重现这些步骤,该过程可以“匿名”上传图像: Private ReadOnly ClientId As String = "My Client ID" ' => "..............."Private ReadOnly ClientSecret As String = "My Client Secr 为了开始执行这个“简单”的任务,我已经研究了一个程序,我已经将其作为示例 here来跟踪并重现这些步骤,该过程可以“匿名”上传图像: @H_403_7@

@H_403_7@

Private Readonly ClIEntID As String = "My ClIEnt ID" ' => "..............."Private Readonly ClIEntSecret As String = "My ClIEnt Secret" ' => "........................................"' Usage:' Dim url As String = UploadImage("C:\Image.jpg") : MessageBox.Show(url)Public Function UploadImage(ByVal image As String)    Dim w As New WebClIEnt()    w.headers.Add("Authorization","ClIEnt-ID " & ClIEntID)    Dim Keys As New System.Collections.Specialized.nameValueCollection    Try        Keys.Add("image",Convert.ToBase64String(file.ReadAllBytes(image)))        Dim responseArray As Byte() = w.UploadValues("https://API.imgur.com/3/image",Keys)        Dim result = EnCoding.ASCII.GetString(responseArray)        Dim reg As New System.Text.RegularExpressions.Regex("link"":""(.*?)""")        Dim match As Match = reg.Match(result)        Dim url As String = match.ToString.Replace("link"":""","").Replace("""","").Replace("\/","/")        Return url    Catch s As Exception        MessageBox.Show("Something went wrong. " & s.Message)        Return "Failed!"    End TryEnd Function
@H_403_7@但我真正想要的是将图像上传到我的用户帐户,即http://elektrostudios.imgur.com.

@H_403_7@我发现this问题,但他在答案中说的不清楚(由于我的新手知识),无论如何我试图使用上面的功能,但只是发送带有我的ClIEntSecret ID的BEARER标题’因为如果我理解为什么oauth 2 api documentation说令牌也可以是ClIEntSecret ID?,但我没有得到预期的结果.

@H_403_7@所以搜索获得正确的访问令牌的方式我已经看到this其他问题帮助我发现RestSharp库并知道如何发送请求,我做了一些修改以使用它与imgur API但我收到此错误-响应:

@H_403_7@

{"data":{"error":"clIEnt_ID and response_type are required","request":"\/oauth2\/authorize","method":"POST"},"success":false,"status":400}
@H_403_7@这就是我所拥有的:

@H_403_7@

Public Sub GetAccesstoken()    Dim xrc As RestClIEnt = New RestClIEnt    Dim grant_type As String = "authorization_code"    Dim request As New RestRequest(Method.POST)    Dim strBody As String    Dim response As RestResponse    Dim strResponse As String    request.Method = Method.POST    request.RequestFormat = DataFormat.Xml    'Base URL    xrc.BaseUrl = "https://API.imgur.com"    'Resource    request.Resource = "oauth2/authorize"    'Format body    strBody = String.Format("clIEnt_ID={0}&response_type={1}",ClIEntID,ClIEntSecret)    'Add body to request    request.AddBody("Authorization",strBody)    'Execute    response = xrc.Execute(request)    'Parse Response    strResponse = response.Content    MessageBox.Show(response.Content.ToString)End Sub
@H_403_7@所以我的问题是2合1:

@H_403_7@

@H_403_7@How I can upload an Image into an imgur user
account using the required things such as the access token?.

@H_403_7@PS:请记住,即使获取访问令牌,我也不知道如何在存储它之后使用它.

@H_403_7@

@H_403_7@UPDATE:

@H_403_7@我正在尝试使用@Plutonix解决方案,但是当我尝试请求令牌时,它会抛出异常“首先需要有效的PIN”,我正在使用有效的ClIEntID和ClIEntSecret,我还缺少更多东西?,这里是码:

@H_403_7@

Private imgur As New imgurAPI("my clIEnt ID","my clIEnt secret")Private Sub button1_Click() Handles button1.Click    Dim wb As New Webbrowser    imgur.RequestPinbrowser(wb)    ' The instruction below throws an exception:    ' "Need a valID PIN first"    Dim result As imgurAPI.imgurResults = imgur.RequestToken    wb.dispose()    ' check result    If result = imgurAPI.imgurResults.OK Then        ' assumes the file exists        imgur.UploadImage("C:\Test.jpg",False)        Clipboard.SetText(imgur.Lastimagelink)        MessageBox.Show(imgur.Lastimagelink)    Else        MessageBox.Show(String.Format("Error getting access token. Status:{0}",result.ToString))    End IfEnd Sub
解决方法 这很长,因为它或多或少是一个完整的API: @H_403_7@

@H_403_7@

Public Class imgurAPI    ' combination of this API and imgur server responses    Public Enum imgurResults        OK = 200                        ' AKA Status200         ' errors WE return        OtherAPIError = -1              ' so far,just missing imglink        InvalIDToken = -2        InvalIDPIN = -3                 ' pins expire        InvalIDRequest = -4        TokenParseError = -5        ' results we get from server        BadRequestFormat = 400          ' Status400           AuthorizationError = 401        ' Status401          ForbIDden = 403                 ' Status403           NotFound = 404                  ' Status404   ' bad URL Endpoint        RatelimitError = 429            ' Status429   ' Ratelimit Error        ServerError = 500               ' Status500   ' internal server error        UkNownStatus = 700              ' We havent accounted for it (yet),'   may be trivial or new    End Enum    ' container for the cool stuff they send us    FrIEnd Class Token        Public Property AcctUsername As String        Public Property Accesstoken As String        Public Property RefreshToken As String        Public Property Expiry As DateTime        Public Sub New()            AcctUsername = ""            Accesstoken = ""            RefreshToken = ""            Expiry = DateTime.MinValue        End Sub        FrIEnd Function IsExpired() As Boolean            If (Expiry > DateTime.Now) Then                Return False            Else                ' if expired reset everything so some moron doesnt                ' expose Accesstoken and test for ""                AcctUsername = ""                Accesstoken = ""                RefreshToken = ""                Expiry = DateTime.MinValue                Return True            End If        End Function    End Class    ' NO simple ctor!!!    ' constructor initialized with ClIEntID and SecretID    Public Sub New(clID As String,secret As String)        clIEntID = clID        clIEntSecret = secret        myPin = ""        imgToken = New Token        Lastimagelink = ""        UseClipboard = True        AnonOnly = False    End Sub    ' constructor initialized with ClIEntID and SecretID    Public Sub New(clID As String)        clIEntID = clID        clIEntSecret = ""        myPin = ""        imgToken = New Token        Lastimagelink = ""        UseClipboard = True        AnonOnly = True    End Sub    Private clIEntID As String    Private clIEntSecret As String    Private AnonOnly As Boolean = True    ' tokens are not public    Private imgToken As Token    Public Property Lastimagelink As String    Public Property UseClipboard As Boolean    ' precise moment when it expires for use in code    Public Readonly Property TokenExpiry As DateTime        Get            If imgToken IsNot nothing Then                Return imgToken.Expiry            Else                Return nothing            End If        End Get    End Property    Public Function GetExpiryCountdown() As String        Return String.Format("{0:hh\:mm\:ss}",GetExpiryTimeRemaining)    End Function    ' time left as a TimeSpan    Public Function GetExpiryTimeRemaining() As TimeSpan        Dim ts As New TimeSpan(0)        If imgToken Is nothing Then            Return ts        End If        If DateTime.Now > imgToken.Expiry Then            Return ts        Else            ts = imgToken.Expiry - DateTime.Now            Return ts        End If    End Function    Public Function IsTokenValID() As Boolean        If imgToken Is nothing Then            Return False        End If        If String.IsNullOrEmpty(imgToken.AcctUsername) Then            Return False        End If        If imgToken.IsExpired Then            Return False        End If        Return True    End Function    ' Currently,the PIN is set from a calling App.  Might be possible    ' to Feed the log in to imgur to get a PIN    Private myPin As String    Public writeonly Property Pin As String        Set(value As String)            myPin = value        End Set    End Property    ' Navigates to the web page.    ' see wb_documentCompleted for code to     ' parse the PIN from the document    Public Sub RequestPinbrowser(browserCtl As Webbrowser)        If AnonOnly Then            ' you do not need a PIN for Anon            Throw New ApplicationException("A PIN is not needed for ANON Uploads")            Exit Sub        End If        If browserCtl Is nothing Then            Throw New ArgumentException("Missing a valID Webbrowser reference")            Exit Sub        End If        ' imgur API format        ' https://API.imgur.com/oauth2/authorize?clIEnt_ID=YOUR_CLIENT_ID&response_type=REQUESTED_RESPONSE_TYPE&state=APPliCATION_STATE        Dim OAuthUrlTemplate = "https://API.imgur.com/oauth2/authorize?clIEnt_ID={0}&response_type={1}&state={2}"        Dim ReqURL As String = String.Format(OAuthUrlTemplate,clIEntID,"pin","ziggy")        browserCtl.Url = New Uri(ReqURL)    End Sub    Public Function GetAccesstoken() As imgurResults        ' there are different types of token requests        ' which vary only by the data submitted        Dim sReq As String = String.Format("clIEnt_ID={0}&clIEnt_secret={1}&grant_type=pin&pin={2}",clIEntSecret,myPin)        If myPin = String.Empty Then            Return imgurResults.InvalIDPIN        End If        If AnonOnly Then Return imgurResults.InvalIDRequest        ' call generic token processor        Return RequestToken(sReq)    End Function    ' request a Token     Private Function RequestToken(sRequest As String) As imgurResults        Dim url As String = "https://API.imgur.com/oauth2/token/"        Dim myResult As imgurResults = imgurResults.OK        ' create request for the URL,using POST method        Dim request As WebRequest = WebRequest.Create(url)        request.Method = "POST"        ' convert the request,set content format,length        Dim data As Byte() = System.Text.EnCoding.UTF8.GetBytes(sRequest)        request.ContentType = "application/x-www-form-urlencoded"        request.ContentLength = data.Length        ' write the date to request stream        Dim dstream As Stream = request.GetRequestStream        dstream.Write(data,data.Length)        dstream.Close()        ' Json used on the response and potential WebException        Dim Json As New JavaScriptSerializer()        ' prepare for a response        Dim response As WebResponse = nothing        Dim SvrResponses As Dictionary(Of String,Object)        Try            response = request.GetResponse            ' convert status code to programmatic result            myResult = GetResultFromStatus(CType(response,httpWebResponse).StatusCode)        Catch ex As WebException            ' a bad/used pin will throw an exception            Dim resp As String = New StreamReader(ex.Response.GetResponseStream()).ReadToEnd()            SvrResponses = CType(Json.DeserializeObject(resp.ToString),Dictionary(Of String,Object))            myResult = GetResultFromStatus(Convert.ToString(SvrResponses("status")))        End Try        'Console.Writeline(CType(response,httpWebResponse).StatusDescription)        'Console.Writeline(CType(response,httpWebResponse).StatusCode)        ' premature evacuation        If myResult <> imgurResults.OK Then            If dstream IsNot nothing Then                dstream.Close()                dstream.dispose()            End If            If response IsNot nothing Then                response.Close()            End If            Return myResult        End If        ' read the response stream        dstream = response.GetResponseStream        Dim SvrResponseStr As String        Using sr As StreamReader = New StreamReader(dstream)            ' stream to string            SvrResponseStr = sr.ReadToEnd            'Console.Writeline(SvrResponse)        End Using        ' close streams        dstream.Close()        dstream.dispose()        response.Close()        Try            ' use Json serialIEr to parse the result(s)            ' convert SvrRsponse to Dictionary            SvrResponses = CType(Json.DeserializeObject(SvrResponseStr),Object))            ' get stuff from Dictionary            imgToken.Accesstoken = Convert.ToString(SvrResponses("access_token"))            imgToken.RefreshToken = Convert.ToString(SvrResponses("refresh_token"))            imgToken.AcctUsername = Convert.ToString(SvrResponses("account_username"))            ' convert expires_in to a point in time            Dim nExp As Integer = Convert.ToInt32(Convert.ToString(SvrResponses("expires_in")))            imgToken.Expiry = Date.Now.Add(New TimeSpan(0,nExp))            ' Pins are single use            ' throw it away since it is no longer valID             myPin = ""        Catch ex As Exception            'MessageBox.Show(ex.Message)            myResult = imgurResults.TokenParseError        End Try        Return myResult    End Function    ' public interface to check params before trying to upload    Public Function UploadImage(filename As String,Optional Anon As Boolean = False) As imgurResults        If AnonOnly Then            Return DoImageUpLoad(filename,AnonOnly)        Else            If IsTokenValID() = False Then                Return imgurResults.InvalIDToken            End If        End If        ' should be the job of the calling app to test for fileExist        Return DoImageUpLoad(filename,Anon)    End Function    ' actual file uploader    Private Function DoImageUpLoad(filename As String,Optional Anon As Boolean = False) As imgurResults        Dim result As imgurResults = imgurResults.OK        Lastimagelink = ""        Try            ' create a WebClIEnt             Using wc = New Net.WebClIEnt()                ' read image                Dim values = New nameValueCollection() From                        {                            {"image",Convert.ToBase64String(file.ReadAllBytes(filename))}                        }                ' type of headers depends on whether this is an ANON or ACCOUNT upload                If Anon Then                    wc.headers.Add("Authorization","ClIEnt-ID " + clIEntID)                Else                    wc.headers.Add("Authorization","Bearer " & imgToken.Accesstoken)                End If                ' upload,get response                Dim response = wc.UploadValues("https://API.imgur.com/3/upload.xml",values)                ' read response converting byte array to stream                Using sr As New StreamReader(New MemoryStream(response))                    Dim uplStatus As String                    Dim SvrResponse As String = sr.ReadToEnd                    Dim xdoc As Xdocument = Xdocument.Parse(SvrResponse)                    ' get the status of the request                    uplStatus = xdoc.Root.Attribute("status").Value                    result = GetResultFromStatus(uplStatus)                    If result = imgurResults.OK Then                        Lastimagelink = xdoc.Descendants("link").Value                        ' only overwrite the server result status                        If String.IsNullOrEmpty(Lastimagelink) Then                            ' avoID NRE elsewhere                            Lastimagelink = ""                            ' we dID something wrong parsing the result                            ' but this one is kind of minor                            result = imgurResults.OtherAPIError                        End If                    End If                End Using                If UseClipboard AndAlso (result = imgurResults.OK) Then                    Clipboard.SetText(Lastimagelink)                End If            End Using        Catch ex As Exception            Dim errMsg As String = ex.Message            ' rate limit            If ex.Message.Contains("429") Then                result = imgurResults.RatelimitError                ' internal error            ElseIf ex.Message.Contains("500") Then                result = imgurResults.ServerError            End If        End Try        Return result    End Function    Private Function GetResultFromStatus(status As String) As imgurResults        Select Case status.Trim            Case "200"                Return imgurResults.OK            Case "400"                Return imgurResults.BadRequestFormat            Case "401"                Return imgurResults.AuthorizationError            Case "403"                Return imgurResults.ForbIDden            Case "404"                Return imgurResults.NotFound            Case "429"                Return imgurResults.RatelimitError            Case "500"                Return imgurResults.ServerError            Case Else                ' Stop - work out other returns                Return imgurResults.UkNownStatus        End Select    End Function    Private Function GetResultFromStatus(status As Int32) As imgurResults        ' some places we get a string,others an integer        Return GetResultFromStatus(status.ToString)    End FunctionEnd Class
@H_403_7@如何使用它

@H_403_7@该过程需要Web浏览器以供用户导航和请求PIN.对于测试/开发,我使用了一个Webbrowser控件并从返回的页面中获取了PIN.

@H_403_7@注意:对于测试,我的imgur帐户设置为DESKtop,因为我们是从DESKtop应用程序发送的.此外,这是您将图像发送到您的帐户.其他人没有办法上传到您的帐户,而不会在应用程序中提供您的秘密ID和/或嵌入您的主imgur登录名和密码.这就是imgur设计它的方式.

@H_403_7@A.创建一个imgur对象:

@H_403_7@

FrIEnd imgur As imgurAPIimgur = New imgurAPI(<your ClIEnt ID>,<your secret code>)
@H_403_7@B.获得一个Pin – 方法一

@H_403_7@

' pass the app's Webbrowser Controlimgur.RequestPinbrowser(wb)
@H_403_7@这会将您带到一个imgur页面,您必须在其中授权发布PIN才能上传到您的帐户.输入您的帐户名称,密码,单击“允许”.将显示带有PIN的新页面.将PIN从网页复制到其他控件,可以将其提供给imgurAPI类.

@H_403_7@下面有代码来解析PIN页面并将其转换为另一个控件.

@H_403_7@方法二

@H_403_7@>使用您自己的外部浏览器,转到

@H_403_7@https://API.imgur.com/oauth2/authorize? CLIENT_ID = YOUR_CLIENT_ID&安培; RESPONSE_TYPE =销&安培;状态=齐格

@H_403_7@>登录
>将您收到的PIN复制到TextBox或其他内容,以将其发送到imgurAPI:
>设置图钉:imgur.Pin =<<你收到的PIN>>

@H_403_7@无论哪种方式都是相同的,只需要在表单中包含Webbrowser控件即可. PIN只能在短时间内使用,因此您必须立即使用它来获取访问令牌.

@H_403_7@C.获取访问令牌

@H_403_7@

' imgurResults is an enum exposed by the classDim result As imgurAPI.imgurResults = imgur.RequestToken
@H_403_7@笔记:

@H_403_7@> imgur类将保留令牌
>令牌目前在1小时(3600秒)到期

@H_403_7@D:上传文件
使用imgur.UploadImage上传(文件名,boolAnon)

@H_403_7@文件名 – 要上载的文件

@H_403_7@boolAnon – 布尔标志. False =将此文件上传到您的帐户,而不是Anon常规池方法.

@H_403_7@例:

@H_403_7@

' get tokenDim result As imgurAPI.imgurResults = imgur.RequestToken' check resultIf result = imgurAPI.imgurResults.OK Then    ' assumes the file exists    imgur.UploadImage("C:\Temp\London.jpg",False)Else    MessageBox.Show(String.Format("Error getting access token. Status:{0}",result.ToString))End If
@H_403_7@文件上载后,该过程将在响应中查找链接.如果可以解析链接,它将从Lastimagelink属性中获得并粘贴到ClipBoard.

@H_403_7@其他属性,设置和方法

@H_403_7@Lastimagelink(String) – 上传的最后一张图片的URL

@H_403_7@UseClipBoard(Bool) – 当为true时,imgurAPI类将上传图像的链接发布到剪贴板

@H_403_7@TokenExpiry(Date) – 当前令牌到期的DateTime

@H_403_7@GetTokenTimeRemaining()As TimeSpan – 表示当前令牌到期前多长时间的TimeSpan

@H_403_7@公共函数GetTokenCountdown()As String – TimeRemaining的格式化字符串

@H_403_7@Public writeonly Property Pin As String – 获取访问令牌所需的PIN

@H_403_7@公共函数IsTokenValID()As Boolean – 当前标记有效

@H_403_7@Public Function IsTokenExpired()As Boolean – TimeRemaining与DateTime.Now的简单布尔版本

@H_403_7@笔记

@H_403_7@>令牌可以续订或扩展.但由于它们持续了一个小时,这似乎很多.
> PINS只能在短时间内使用.一旦PIN被交换为令牌,imgurAPI(此类)将清除PIN.如果获取令牌时出现问题,则必须先获取新的PIN(如果几分钟前刚刚获得,则粘贴最后一个).
>除非/直到您更改帐户设置,否则整个世界都无法看到上传的图片.
>您可以重置您的SecretID(设置 – >应用程序).如果这样做,您还需要为使​​用此API类的应用重置它,并重新编译(或从配置文件中读取).

@H_403_7@如果使用Webbrowser控件获取PIN,则可以将此代码添加到documentCompleted事件中以从HTML中删除PIN:

@H_403_7@

' wb is the controlDim HTMLDoc As System.windows.Forms.HTMLdocument = wb.documentDim elP As System.windows.Forms.HTMLElement = HTMLDoc.GetElementByID("pin")If elP IsNot nothing Then    sPin = elP.GetAttribute("value")    If String.IsNullOrEmpty(sPin) = False Then       ' user has to push the button for `imgur.Pin = tbPIN.Text`       ' this is in case the HTML changes,the user can overrIDe       ' and input the correct PIN       Me.tbPIN.Text = sPin    End IfEnd If
@H_403_7@关于OAuth模型

@H_403_7@这是非官方的 – 从阅读文档和使用API​​学到的信息.适用于此日期的imgur API v3.

@H_403_7@获取PIN码没有任何自动化.无论如何,您必须导航到浏览器中的URL并输入您的帐户名和密码才能获得PIN.这是设计使您自己亲自授权某些外部应用访问您的帐户内容.

@H_403_7@上面的方法一使用.NET Webbrowser控件来执行此 *** 作.使用此方法,我们可以确保您和imgur类都使用相同的Endpoint / URL,因为它通过浏览器控件将您发送到那里.

@H_403_7@方法二只是你在某个浏览器,任何浏览器去那里.登录,获取PIN,然后将其粘贴到imgurAPI类.

@H_403_7@无论方法如何,要使用的正确端点/ URL是:

@H_403_7@https://api.imgur.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=pin&state=foobar

@H_403_7@使用imgurAPI类在表单上使用浏览器,显然我们可以确定您和类都使用相同的URL和ClIEntID. documentComplete的代码只需将PIN设置到TextBox中,您仍然需要在类中设置它:

@H_403_7@

myimgur.PIN = tbPinCode.Text
@H_403_7@PIN码是一次性使用,并且到期.

@H_403_7@所以在特别开发时,你停止代码,添加一些东西然后自然重新运行,代码将不再有旧的令牌或PIN.如果最后一个PIN是最近的并且未提交,您可能不需要获得新的PIN,但我发现很难记住是否是这种情况.

@H_403_7@该课程将PINS视为一次性使用.一旦收到令牌,它就会清除变量,因为它们已经被使用并且不再有效.

@H_403_7@最终编辑

@H_403_7@>添加了仅限Anon模式

@H_403_7@要使用该类仅以匿名模式(一般网站,而不是您的帐户)上传,不需要SecretID.为此,使用新的构造函数重载:

@H_403_7@

Public Sub New(clIEntID As String)
@H_403_7@这会将类设置为仅使用Anon,并且在使用基于帐户的方法(如GetToken)时,某些方法将返回错误或引发异常.如果使用ClIEntID初始化它,它将保持AnonOnly模式,直到您使用ClIEntID和SecretID重新创建对象.

@H_403_7@没有任何理由将其用作AnonOnly(除非您没有帐户),因为UploadImage方法允许您将其指定为按文件匿名上传:

@H_403_7@

Function UploadImage(filename As String,Optional Anon As Boolean = False) As imgurResults
@H_403_7@>修改/澄清了imgurResults Enum

@H_403_7@这意味着无所不包:一些返回表示类检测到的问题,另一些返回是简单传递的服务器响应.

@H_403_7@>删除了IsTokenExpired

@H_403_7@IsTokenValID更彻底.还有其他方法可以获得剩余时间或实际到期时间.

@H_403_7@>添加了各种错误捕获/处理

@H_403_7@>请求PIN时检查有效的Webbrowser控件
>优化了上传图像后用于获取服务器状态码的方法
>重新设计了一些处理,以便在类返回时优先考虑远程服务器状态

@H_403_7@.

总结

以上是内存溢出为你收集整理的.net – 通过OAuth访问imgUr(上传到用户帐户)全部内容,希望文章能够帮你解决.net – 通过OAuth访问imgUr(上传到用户帐户)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1236002.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存