DOBON.NETプログラミング道掲示板

■35422 / 親記事)  ワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る
  
□投稿者/ けい 一般人(8回)-(2023/05/12(Fri) 19:05:52)
  • アイコン環境/言語:[Windows10、VB.NET2022] 
    分類:[.NET] 

    お世話になります。

    ヤフーのアカウントで、
    開発用のテストアカウントを設け、
    ヤフーのWebAPIを使用するのに必要な、
    「クライアントID」を割り振ってもらっています。

    また、認証を求めるWebAPIを使用するのに必要な、
    アクセストークンという認証文字列を受け取るためのURLである、
    「コールバックURL」を指定しています。

    ヤフーのアクセストークンを取得するためのアクセス先が、
    「Authorizationエンドポイント」と言い、接続先は、
    URL: https://auth.login.yahoo.co.jp/yconnect/v2/authorization
    サポートするHTTPメソッド: GET/POST
    です。

    (参照)
    Authorizationエンドポイント
    https://developer.yahoo.co.jp/yconnect/v2/authorization_code/authorization.html

    プログラムにおいては、
    Form1上のButton1をクリックすると、
    このURLに接続し、自動ログインがなされ、
    アクセストークン情報を含むJSONデータが返り、
    RichTextBox1に表示するようにしたいです。

    そこで、次のようなコードを記述しました。

    ---------------------------------------------

    Imports System.IO
    Imports System.Text

    Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs)
    Handles Button1.Click

    Dim TargetURL As String

    TargetURL="https://auth.login.yahoo.co.jp/yconnect/v2/authorization?client_id=<クライアントID>&response_type=token(or code)&scope=openid&redirect_uri=<コールバックURL>&output=json"

    Using client As New System.Net.Http.HttpClient()
    Using response1 As System.Net.Http.HttpResponseMessage = client.GetAsync(TargetURL).Result

    Dim responseBody1 As String = response1.Content.ReadAsStringAsync().Result
    RichTextBox1.Text = responseBody1.ToString

    End Using
    End Using

    End Sub

    End Class

    ---------------------------------------------

    これを実行しますと、
    RichTextBox1には、JSONデータではなく、
    ヤフーのログイン画面のHTMLが返ります。
    自動ログインができていません。

    ここで、TargetURLも文字列を、ブラウザのURL欄に手動で入れて実行すると、
    ヤフーのログイン画面が表示されます。
    ヤフーのログインでは、パスワードが固定ではなく、
    ユーザーIDを入力したら、ワンタムパスワードを発行し、
    メールまたはスマホのSMSに届いたパスワードを画面に手入力して、
    ログインします。
    そうすると、指定していた「コールバックURL」のサイトがリダイレクト表示され、URL欄に、「#access_token=」とアクセストークンが表示されます。

    この一連の手続きを手動ではなく自動で行いたいので、
    次のようなコードを検討しました。

    「TargetURL=」の後ろの部分です。

    ワンタイムパスワード認証は、Basic認証ではないのかもしれませんが、
    まずは書いてみました。

    (参照)
    https://teratail.com/questions/373083
    ---------------------------------------------

    'Basic認証するユーザ名とパスワード
    Dim userName = "<ユーザーID>"
    Dim userPassword = ""

    'リクエストの生成
    Dim request = New HttpRequestMessage
    request.Method = HttpMethod.Post
    request.RequestUri = New Uri(TargetURL)

    'Basic認証ヘッダを付与する
    request.Headers.Authorization
    =
    New System.Net.Http.Headers.AuthenticationHeaderValue
    ("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes
    (String.Format("{0}:{1}", userName, userPassword))))

    'リクエストの送信
    Dim httpClient = New HttpClient()
    Dim response2 = httpClient.SendAsync(request)
    RichTextBox2.Text = response2.ToString

    ---------------------------------------------

    これを実行しますと、
    RichTextBox2には、
    次のような文字列が返ります。

    System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.Net.Http.HttpResponseMessage,System.Net.Http.HttpClient+<<SendAsync>g__Core|83_0>d]

    上記のコードでは、
    userPassword = ""
    のため、当然ログインができないのだと思いますが、
    ワンタイムパスワードをここでどのように記述すればよいのか、
    わかりませんでした。

    また、PostAsyncを使用する気もすればよい気もするのですが、
    ここでの使い方が分かりませんでした。

    (参照)
    HttpClient.PostAsync メソッド
    https://learn.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclient.postasync?view=net-8.0

    WebRequestでPOSTする方法はネットに例があったのですが、
    廃止されているとのことでした。

    (参照)
    認証が必要なページをダウンロードする
    http://dobon.net/vb/dotnet/internet/usecredentials.html
    WebRequest、WebClient、ServicePoint は廃止されている
    https://learn.microsoft.com/ja-jp/dotnet/core/compatibility/networking/6.0/webrequest-deprecated

    以上、長くなってしまいましたが、
    ワンタイムパスワードを使用するサイトに自動ログインしてアクセストークンを含むJSONデータを取得するには、どのようにしたらよいか。

    可能な範囲でご指導いただきたく、どうぞよろしくお願い申し上げます。


マルチポストを報告
違反を報告
引用返信 削除キー/
■35423 / ResNo.1)  Re[1]: ワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る
□投稿者/ Azulean 大御所(537回)-(2023/05/12(Fri) 21:47:13)
  • アイコン2023/05/12(Fri) 21:48:42 編集(投稿者)

    No35422に返信(けいさんの記事)
    > ワンタイムパスワードを使用するサイトに自動ログインしてアクセストークンを含むJSONデータを取得するには、どのようにしたらよいか。
    >

    結論から言えば「できません」。


    この authorization のサイトをユーザーに表示し、ユーザーがIDやパスワード、ワンタイムパスワードを入力し、アプリケーションがアクセスすることを認めるというのが認証プロセスです。
    これは自動化できません。

    通常、初回(や一定期間経過後)にこの画面を表示してユーザーに権限を求め、以降は得たアクセストークンで処理を実行するように作ります。
    いわゆる OAuth 認証に当たります。
    (アプリケーションに、IDやパスワードを晒すことなく、権限を許可できる仕組み)
違反を報告
引用返信 削除キー/
■35424 / ResNo.2)  Re[2]: ワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る
□投稿者/ けい 一般人(9回)-(2023/05/12(Fri) 22:31:29)
  • アイコンNo35423に返信(Azuleanさんの記事)

    ありがとうございます。

    自動化できない場合、手動でログインした後の状態で、アクセストークンを、ブラウザ経由(マウスでURL表示部分のアクセストークン部分を選択、コピペ)ではなく直接取得する方法がありますでしょうか。

    ブラウザ経由の場合は、例えば、WebBrowserコントロールで画面を表示すれば、URLを取得しやすいようですが、現在このコントロールは終了の方向であるようですね。
    WebView2コントロールというものがあるようで、こちらでテストしてみます。


違反を報告
引用返信 削除キー/
■35425 / ResNo.3)  Re[3]: ワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る
□投稿者/ けい 一般人(10回)-(2023/05/16(Tue) 17:20:49)
  • アイコンNo35423に返信(Azuleanさんの記事)

    お世話になります。

    ブラウザはEdge、コントロールはWebView2を使うことにしました。
    他のブラウザでWebView2を使う方法は調べきれていません。

    (参照)
    Microsoft Edge WebView2
    https://learn.microsoft.com/ja-jp/microsoft-edge/webview2/

    上記のTargetURLをWebView2コントロールに指定して、
    ヤフーのログイン画面を開き、
    届いたワンタイムパスワードでログインします。

    リダイレクトされたサイトのURLにアクセストークンが含まれており、
    それを取得します。

    コードは以下のようになりました。
    WebView2は初期化が必要であること、
    URLを取得する場合は、
    WebView2_NavigationCompleted=Trueになってからでないと取得できない、
    ということでした。

    -------------------------------------

    Async Sub InitializeAsync()
    Await WebView2.EnsureCoreWebView2Async(Nothing)
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    '初期化
    InitializeAsync()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs)
    End Sub Button1.Click
    'サイトを開く
    WebView2.CoreWebView2.Navigate(TargetURL2)
    End Sub

    Module Hensu
    'パブリック変数宣言
    Public intNavigationState As Integer
    End Module

    Private Sub WebView2_NavigationStarting(sender As Object, e As CoreWebView2NavigationStartingEventArgs) Handles WebView2.NavigationStarting
    intNavigationState = 0 'サイト表示開始
    End Sub

    Private Sub WebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView2.NavigationCompleted
    intNavigationState = 1 'サイト表示完了
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs)
    End Sub Button2.Click
    Dim strResponse As String
    If intNavigationState = 1 Then
    'URLを取得する。
    strResponse=WebView2.CoreWebView2.Source
    End If
    End Sub

    -------------------------------------

    ここで得られたstrResponseから、アクセストークンを抽出できました。

    ご指導ご教示を誠にありがとうございました^^。
解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -