5

Quizlet (oauth2) でアクセス トークンを取得するのに苦労しています。これまでのところすべて正常に動作しています。ユーザーが Quizlet でアプリを受け入れてリダイレクトされるようにすることはできますが、NSURLConnection を介してアクセス トークンを要求すると、常に次のエラーが発生します。

2013-08-17 09:39:33.422 Abiliator[49549:c07] 文字列形式で返されたデータ: {"http_code":400,"error":"invalid_request","error_title":"許可され​​ていません","error_description": "grant_type パラメータが無効であるか、パラメータがありません"}

ユーザー認証のコードは次のとおりです (仕様に従ってブラウザー経由で行う必要があります)。

- (void) authenticateQuizletUser
{

NSString *quizletRandomString = [abiliatorAppDelegate GetUUID];
NSString *authURLString = [@"https://quizlet.com/authorize/?response_type=code&client_id=" stringByAppendingString:@"<myID>&scope=read"];
authURLString = [authURLString stringByAppendingString:@"&state="];
authURLString = [authURLString stringByAppendingString:quizletRandomString];
authURLString = [authURLString stringByAppendingString:@"&redirect_uri=Abiliator://after_oauth"];

NSLog(@"Authentication URL sent: %@", authURLString);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: authURLString]];

}

私が述べたように、それはうまくいきます。アプリは Safari を起動し、ユーザーはユーザー ID とパスワードを入力する要求を承認する必要があり、サーバーはアプリにリダイレクトします。これを以下のメソッドでキャッチすると、説明されているエラーがスローされます。

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if (!url) {  return NO; }
NSString *URLString = [url absoluteString];
NSLog(@"Received URL: %@", URLString);
NSString *myURLQuery = [url query];
NSString *myAuthCode = [self getAuthorizationCodeFromURL:myURLQuery];
NSLog(@"Component1: %@", myAuthCode);
NSString *authPasswd = @"myPasswd";
NSString *username=@"myUserName";

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.quizlet.com/oauth/token"]];

request.HTTPMethod = @"POST";

[request setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"Abiliator://after_oauth" forHTTPHeaderField:@"redirect_uri"];

// According to Quizlet API doc: You must set this (grant_type) to the string "authorization_code". 
[request setValue:@"authorization_code" forHTTPHeaderField:@"grant_type"];
[request setValue:myAuthCode forHTTPHeaderField:@"code"];

NSString *authStr = [NSString stringWithFormat:@"%@:%@", username, authPasswd];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedString]];
[request setValue:authValue forHTTPHeaderField:@"Authorization"];

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];


return YES; }

どんな助けでも大歓迎です。

4

4 に答える 4

2

OAuth2では、アクセス トークンを取得する 4 つの方法が定義されています。最も安全で最も複雑なのは、ここで説明されているように Quizlet が使用するAuthorization Code Grantです。

Authorization Code Grant は、次の 2 つのステップで構成されます。

  • 認証コードを取得します (フローがリダイレクト経由で返される前に、ユーザーはアプリの外部でここで認証されます)
  • 認証コードをアクセス トークンに変更する

あなたは最初の電話を正しくしました。2 番目の呼び出しの問題は、grant_typeパラメーターを要求の間違った場所に置くことです。この行では、HTTP ヘッダーとして扱います。

[request setValue:@"authorization_code" forHTTPHeaderField:@"grant_type"];

また、ここでは認証コードを HTTP ヘッダーとして扱います。

[request setValue:myAuthCode forHTTPHeaderField:@"code"];

ただし、OAuth2 では、両方をリクエストの本文に入れる必要があります。正しいリクエストの例を次に示します。

POST /oauth/token/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 999
Authorization: Basic xxx

grant_type=authorization_code&code=theCodeYouGotInTheFirstStep&
scope=somescope&redirect_uri=theSameUriYouIncludedEarlier

(空行の下はリクエストの本文です)
(読みやすくするためだけに本文に改行を追加しました - リクエストに含めないでください)

おまけの答え: OAuth2 はデフォルトでは安全ではないことに注意してください: OAuth2 RFC にも記載されているように、少し余分な作業を行わないと、アプリはクロスサイト リクエスト フォージェリ攻撃に対して脆弱になります。これを防ぐために、OAuth2 はパラメーターを提供します。推測できない値を生成し、それを最初のリクエストに含める必要があります。サーバーから返された が以前に生成したものと異なる場合は、2 番目の要求を発行してはなりません。statestatestate

于 2013-08-30T11:00:37.593 に答える
1

残りの実装を確認するのに役立つ場合があります。をどのように入手していcodeますか? また、どの資格情報 ( authPasswd& username) を使用していますか? これらは (エンド ユーザーのものではなく) アプリのものである必要があります。これらは Quizlet の開発ダッシュボードで入手できます。

注: この OAuth フローは、シークレットをデバイスに保存する必要があるため、デバイスにはお勧めしません。フローを使用するimplicitことは可能ですが、Quizlet がそれをサポートしているかどうかはわかりません。

于 2013-08-17T16:14:04.163 に答える
0

oauth パラメータをペイロードとして送信します。それらをヘッダーとして送信しないでください。たとえば、リクエストは次のようになります

POST /token 

Headers:

Authorization: Basic R0cxSWJdHpINDVhang5Y0VlSUxxalBSOW5SU0NBWA==

Content-Type: application/x-www-form-urlencoded

Payload:

grant_type=authorization_code&code=Wirr951e&scope=READ&redirect_uri=www.google.com
于 2013-08-27T19:21:07.810 に答える