質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

15874閲覧

C#のHttpClientでのCookieを使ったログインの維持

kurikinton105

総合スコア5

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

1グッド

0クリップ

投稿2020/04/05 15:11

編集2020/04/06 15:37

前提・実現したいこと

C#のHttpClientでURIにjsonデータを送り、ログインするというプログラムを作っています。
ログインすることはできたのですが、Cookieの保持がおそらくできておらず、ログイン後のユーザーの情報が得られません。勉強中で初歩的なものかもしれませんが教えていただきたいです。

発生している問題・エラーメッセージ

ログイン(http://developers.u-aizu.ac.jp/api?key=judgeapi/session_POST後に、ユーザーの"self"情報が得られない(ログインのみできる)

下のメッセージはselfのGET(http://developers.u-aizu.ac.jp/api?key=judgeapi%2Fself_GET)を送った時のメッセージです。

[{"id":1102,"code":"INVALID_REFRESH_TOKEN_ERROR","message":"This user is expired."}]``` ```C# ソースコード ```C# class API { //Login private void Login() { string user, password; Console.WriteLine("username >>>"); user = Console.ReadLine(); Console.WriteLine("password >>>"); password = Console.ReadLine(); var task = Task.Run(() => { return Post_Login(user, password); }); var result = task.Result;        Console.WriteLine(task.Result); //ログイン情報の表示がされる } async public Task<string> Post_Login(string id, string pass) { var parameters = new Dictionary<string, string>() { }; var json = "{\"id\":\"" + id + "\",\"password\":\"" + pass + "\"}"; Console.WriteLine(json); //json確認用の表示 var content = new StringContent(json, Encoding.UTF8, "application/json"); // クッキー準備 CookieContainer cc = new CookieContainer(); cc.Add(new Uri("https://judgeapi.u-aizu.ac.jp"), new Cookie("test", "value")); using (var handler = new HttpClientHandler()) using (var client = new HttpClient()) { var response = await client.PostAsync($"https://judgeapi.u-aizu.ac.jp/session", content); var cookie = response.Headers.GetValues("Set-Cookie").First(); Console.WriteLine("content ->> " + content); Console.WriteLine("cookie --> " + cookie + "\n"); content.Headers.Add("Cookie", cookie); // クッキー設定 handler.CookieContainer = cc; //クッキー保存 cc = handler.CookieContainer; Console.WriteLine("cc --> " + cc.ToString()); return await response.Content.ReadAsStringAsync(); } } //GET関数 Get(URI)で実行 private void Get(string URI) { var task = Task.Run(() => { return GET(URI); }); string[] numbers = new string[100]; String str = task.Result; System.Console.WriteLine(str); //selfデータの表示(ここでエラーが起きる) } async public Task<string> GET(string URI) { using (var client = new HttpClient()) { var uri = $"" + URI + ""; var response = await client.GetAsync(uri); //UTF-8として変換 return await response.Content.ReadAsStringAsync(); } }      public static void Main(string[] args) { API obj = new API(); obj.Login(); //ログインの関数を呼び出す obj.Get("https://judgeapi.u-aizu.ac.jp/self"); //selfデータを得る(この関数内でエラーが起きる)

試したこと

selfのGETを送った際に、ユーザー認証がうまくいっていないので、おそらくCookieの保存がうまくいっていないのではと思いました。
https://teratail.com/questions/14551 色々調べてみたのですが解決できなかったです。

補足情報

visual studio for mac,.Net Framework4.7.2,

http://developers.u-aizu.ac.jp/index
のapiを使っています。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/05 21:57

クッキーではなくてトークンと言うことはないですか? Web API はベアラトークンを使うケースが多いように思います。
guest

回答2

0

ベストアンサー

GETHttpClientを作り直してるからじゃないですか?
あとクッキーを使いたいだけなら、UseCookies = trueでいいんじゃないですかね。

cs

1using System; 2using System.Diagnostics; 3using System.Linq; 4using System.Net.Http; 5using System.Text; 6using System.Threading.Tasks; 7 8namespace Questions251616 9{ 10 static class Program 11 { 12 static async Task Main() 13 { 14 Console.Write("username >>>"); 15 var user = Console.ReadLine(); 16 17 Console.Write("password >>>"); 18 var password = Console.ReadLine(); 19 20 var obj = new API(); 21 var result = await obj.LoginAsync(user, password); 22 Console.WriteLine(result); 23 Console.WriteLine(); 24 25 var self = await obj.SelfAsync(); 26 Console.WriteLine(self); 27 28 Console.ReadKey(); 29 } 30 } 31 32 public class API 33 { 34 // 長いw 35 private static readonly HttpClient client = new HttpClient(new HttpClientHandler() { UseCookies = true, }) 36 { 37 BaseAddress = new Uri("https://judgeapi.u-aizu.ac.jp/"), 38 }; 39 40 public async Task<string> LoginAsync(string id, string pass) 41 { 42 var json = $@"{{""id"":""{id}"",""password"":""{pass}""}}"; 43 Debug.WriteLine(json); 44 45 var content = new StringContent(json, Encoding.UTF8, "application/json"); 46 var response = await client.PostAsync("session", content); 47 Debug.WriteLine($"content ->> {content}"); 48 49 if(response.Headers.Contains("Set-Cookie")) 50 { 51 var cookie = response.Headers.GetValues("Set-Cookie").First(); 52 Debug.WriteLine($"cookie --> {cookie}\n"); 53 } 54 55 return await response.Content.ReadAsStringAsync(); 56 } 57 58 public Task<string> SelfAsync() => GetAsync("self"); 59 60 public async Task<string> GetAsync(string uri) 61 { 62 var response = await client.GetAsync(uri); 63 return await response.Content.ReadAsStringAsync(); 64 } 65 } 66}

.NET(Framework)のHttpClientの取り扱いには要注意という話 - Qiita
を見るとStaticUseCookies = trueも要注意なのですが^^;

投稿2020/04/06 14:00

編集2023/07/21 09:29
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurikinton105

2020/04/06 15:27

HttpClientを作り直していたので、GET関数内で全てリセットされていた(違う通信をはじめていたという感じ?)だったのですね。Cookieの設定を決してやっても同じ結果なので、HttpClientを作り直していたことが直接の原因そうです。ありがとうございます。
guest

0

質問のコメント欄で、

クッキーではなくてトークンと言うことはないですか?

とコメントしましたが、質問に書いてある、

http://developers.u-aizu.ac.jp/index
のapiを使っています。

を見る限り、クッキーもトークンも関係なくて、id と password の JSON 文字列を POST すれば、それらが有効であれば Response example に書いてあるような JSON 文字列が返ってくるというように読めます。

ログイン後に、ユーザーの"self"情報が得られない(ログインのみできる)
selfの情報を送った時のメッセージです。

「ログイン後」とか「selfの情報を送った」というのはどういう意味なのでしょうか?

それが分かりませんが、もし、質問に書いてある http://developers.u-aizu.ac.jp/index の通り id と password の JSON 文字列を POST 送信した結果のエラーメッセージが "This user is expired." であれば、送信した id, Password が無効ということのように読めますが。

投稿2020/04/06 01:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurikinton105

2020/04/06 02:53

ありがとうございます。書き方に不足部分が多くてご迷惑をかけてしまいすみません。 上のコードでは、http://developers.u-aizu.ac.jp/api?key=judgeapi/session_POST のidとpasswordの認証はできていました(帰ってくる値がResponse example に書いてあるような JSON 文字列でした) 今回エラーが起きてしまったのは、上のloginのPOSTを送った後にユーザーのsession infoを取得する( http://developers.u-aizu.ac.jp/api?key=judgeapi%2Fself_GET ) このGETを送信すると、[{"id":1102,"code":"INVALID_REFRESH_TOKEN_ERROR","message":"This user is expired."}]というメッセージが返されるということです。(質問ではこれをselfのデータと略していました。 すごくわかりにくくてすみません。
退会済みユーザー

退会済みユーザー

2020/04/06 04:34

そもそもユーザー認証の仕組みの仕様は明確になっているのでしょうか? クッキーを使っているということに間違いないですか? であれば、クッキーが送られてきていることを Fiddler などで調べてみたでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問