Androidã®AccountManagerçµç±ã§Googleã®OAuth2èªè¨¼ãè¡ãã«ã¯?(å¤é¨ã©ã¤ãã©ãªå®å ¨éä¾åç)
以åã«Androidã§OAuth2èªè¨¼ãããæ¹æ³ã«ã¤ãã¦ã¯æ¸ãããã¨ããã。ãã ã、WebViewçµç±ã ã£ã。
ç´ç·æ¢æ»: Androidã§Googleã®OAuth2èªè¨¼ãè¡ãã«ã¯?(å¤é¨ã©ã¤ãã©ãªå®å ¨éä¾åç)
WebViewçµç±ã§ã¯å¿ ãã¦ã¼ã¶ã¼ã«IDã¨ãã¹ã¯ã¼ããå ¥åãã¦ãããå¿ è¦ãããã、AccountManagerçµç±ã ã¨ãã§ã«ã¢ã«ã¦ã³ãæ å ±ã端æ«ã«å ¥åãã¦ãããªãå ¥åãã¦ãããå¿ è¦ããªããªã。
ãã 、AccountManagerçµç±ã®OAuth2ã¯å¿ ãããã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ã¨ã¯è¨ããªãé¨åããã。
ç´ç·æ¢æ»: Androidã®ã¢ã«ã¦ã³ãããã¼ã¸ã£ã¼çµç±ã®OAuth2ã¯æ¬å½ã«ã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ãªã®ã?
ç´ç·æ¢æ»: Androidã®AccountManagerã使ã£ãOAuth2èªè¨¼ã¯ä½ã ãæªãã
ããã、å¤ãã®ã¦ã¼ã¶ã¼ã«ã¨ã£ã¦ã¯ã¢ã«ã¦ã³ãæ å ±ã®å ¥åãçãã¦ãããæ¹ãã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ã¨è¨ããã®ãããããªãã¨æã£ã。ããã§ä»åº¦ã¯AccountManagerçµç±ã§è¡ãæ¹æ³ãã¾ã¨ãã¦ã¿ããã¨æã。
ãã®ãããªãã¹ãã¢ããªãä½ã£ã。
Eclipseããã¸ã§ã¯ããã¡ã¤ã«:AccountManagerOAuth2.zip (694KB)
å¤ãã®å¦çã¯tasks-android-sampleãåèã«ãã。
ããã°ã©ãã³ã°ã«å ¥ãåã«AndroidManifest.xmlã§ãã¼ããã·ã§ã³ãè¨å®ãã¦ãããªããã°ãªããªã。
ãããã®ãã¼ããã·ã§ã³ã¯å ¨ã¦å¿ è¦ã 。
ã¾ãã¯「ã¦ã¼ã¶ã¼æ å ±åå¾」ãã¿ã³ãã¯ãªãã¯ãã。ããã¨onClickBtnUserInfo()ãå¼ã³åºããã。
AUTH_TOKEN_TYPE_PROFILEã¯Googleã®ã¦ã¼ã¶ã¼æ å ±ãåå¾ããããã®APIã®URLã 。ãã®ã¡ã½ããã«ããstartRequest()ãå¼ã³åºããã。
èµ·åç´å¾ã¯accountNameã¯nullãªã®ã§chooseAccount()ãå¼ã³åºããã。
accountManager.getAuthTokenByFeatures()ã¯ç«¯æ«ã«å ¥åããã¦ããã¢ã«ã¦ã³ãæ°ã«ãã£ã¦ç°ãªãåä½ããã。ä¸é£ã®ç»é¢ã¯ã¢ããªã§ã¯ãªãOSãç¨æããç»é¢ã 。
ã¢ã«ã¦ã³ããã¼ããªã、ã¢ã«ã¦ã³ãã使ããç»é¢ã«ãªã。ã¢ã«ã¦ã³ãã使ããå¾、ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã«èªå°ããã。
ã¢ã«ã¦ã³ããï¼ã¤ãªã、鏿ç»é¢ãåºãã«、ããã¢ã¯ã»ã¹è¨±å¯ç»é¢ã表示ããã。
ããã§åé¡ãªã®ã¯、URLããã®ã¾ã¾åºã¦ãã¾ã£ã¦ãããã¨。ICS以éã ã¨åããããã説æãåºãå ´åãããããã ãã©、ãã以åã®OSã§ã¯è«¦ãããããªãããã 。
ã¢ã«ã¦ã³ããï¼ã¤ä»¥ä¸ãªã、ã¢ã«ã¦ã³ãã鏿ããç»é¢ã«ãªã£ã¦、鏿ããã¨ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã表示ããã。
ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§AllowãDenyãããã¨onGetAuthToken()ãå¼ã³åºããã。
Denyããå ´åã¯future.getResult()ããæ®µéã§OperationCanceledExceptionãã¹ãã¼ããã。ã¤ã¾ããã£ã³ã»ã«æ±ã。
Allowããå ´åã¯OAuth2ã®å¦çãOSãèªåçã«è¡ã£ãçµæ、accountNameã¨authTokenãåå¾ã§ãã。ãã®å¾ã¯authTokenTypeã«è¨å®ãããå¤ã«å¾ã£ã¦getUserInfo()ãå¼ã³åºããã。
getUserInfo()ã§æ£å¸¸ã«ã¦ã¼ã¶ã¼æ å ±ãåå¾ã§ããã、次ã¯「AdSenseã¬ãã¼ãåå¾」ãã¿ã³ãã¯ãªãã¯ãã。ããã¨onClickBtnAdSense()ãå¼ã³åºããã。
ããã§ã¾ãstartRequest()ãå¼ã³åºããã。ãã ã、弿°ãAUTH_TOKEN_TYPE_ADSENSEã«ãªã£ã¦ãããã¨ã«æ³¨æ。
ä»åã¯accountNameãnullã§ã¯ãªãã®ã§getAuthToken()ãå¼ã³åºããã。
ã¾ãaccountNameããaccountãæ¤ç´¢ãã。ããã¦、ãã®accountã使ã£ã¦accountManager.getAuthToken()ãå¼ã¶。
ãã®å ã®åä½ã¯APIã®ä½¿ç¨è¨±å¯ãåºã¦ãããã©ããã§ç°ãªã。
ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããå ´åã¯、ããã«AuthTokenãåå¾ã§ããã®ã§onGetAuthToken()ãå¼ã¶。
ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããªãå ´åã¯、ããã«AuthTokenãåå¾ã§ããªãã®ã§、Intentã使ã£ã¦ã¢ã¯ã»ã¹è¨±å¯ç»é¢ãå¼ã³åºã。ä»åã¯ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããªãã®ã§ãã®ã±ã¼ã¹。
ããã§Allowããã¦ãDenyããã¦ãonActivityResult()ãå¼ã°ãã。
ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§Allowããããæ¢åºã®getAuthToken()ãå度å¼ã³åºã。
ä»åº¦ã¯ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããã®ã§「ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããå ´å」ã«ããã、getAuthToken()å ã§æ¢åºã®onGetAuthToken()ãå¼ã°ãã。
ããã¦ä»åã¯onGetAuthToken()å ã§getAdSenseReport()ãå¼ã°ãã。
authTokenã¯ä¸å®æééããã¨ç¡å¹ã«ãªãã®ã§ååå¾ããå¿ è¦ããã。
ä¸å®æéãéããauthTokenã使ã£ã¦APIã«ãªã¯ã¨ã¹ãããã¨「"code":401」ãå«ãjsonãè¿ããã。ä¸ã§ã¯「else if (json.toString().contains(KEY_AUTH_ERROR))」ã®ã±ã¼ã¹ã 。
ãã®ã±ã¼ã¹ã§ã¯accountManager.invalidateAuthToken()ããå¾startRequest()ãå度å¼ã³åºã。ããã¨æ´æ°ãããauthTokenãåå¾ã§ããããã«ãªã、ã¨ã©ã¼ç¡ããªã¯ã¨ã¹ãã§ããããã«ãªã。
以ä¸ã®ããã«ãã¦AccountManagerçµç±ã®OAuth2èªè¨¼ã§è¤æ°ã®Google APIã«ã¢ã¯ã»ã¹ã§ãã。
OAuth2ã®å¦çã«ã¤ãã¦ã¯é è½ããã¦ããã®ã§å ¨ãåãããªã。éå¸¸å¿ è¦ãªClientIDãClientSecretãå¿ è¦ãªãããã。APIã«ãªã¯ã¨ã¹ãæããæã«ã¤ãã¦ãã£ãã»ããããã®ããª?ãã®é¨åã«ã¤ãã¦ã¯ããå°ã調ã¹ãå¿ è¦ããã。
ç´ç·æ¢æ»: Androidã§Googleã®OAuth2èªè¨¼ãè¡ãã«ã¯?(å¤é¨ã©ã¤ãã©ãªå®å ¨éä¾åç)
WebViewçµç±ã§ã¯å¿ ãã¦ã¼ã¶ã¼ã«IDã¨ãã¹ã¯ã¼ããå ¥åãã¦ãããå¿ è¦ãããã、AccountManagerçµç±ã ã¨ãã§ã«ã¢ã«ã¦ã³ãæ å ±ã端æ«ã«å ¥åãã¦ãããªãå ¥åãã¦ãããå¿ è¦ããªããªã。
ãã 、AccountManagerçµç±ã®OAuth2ã¯å¿ ãããã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ã¨ã¯è¨ããªãé¨åããã。
ç´ç·æ¢æ»: Androidã®ã¢ã«ã¦ã³ãããã¼ã¸ã£ã¼çµç±ã®OAuth2ã¯æ¬å½ã«ã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ãªã®ã?
ç´ç·æ¢æ»: Androidã®AccountManagerã使ã£ãOAuth2èªè¨¼ã¯ä½ã ãæªãã
ããã、å¤ãã®ã¦ã¼ã¶ã¼ã«ã¨ã£ã¦ã¯ã¢ã«ã¦ã³ãæ å ±ã®å ¥åãçãã¦ãããæ¹ãã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ã¨è¨ããã®ãããããªãã¨æã£ã。ããã§ä»åº¦ã¯AccountManagerçµç±ã§è¡ãæ¹æ³ãã¾ã¨ãã¦ã¿ããã¨æã。
ãã®ãããªãã¹ãã¢ããªãä½ã£ã。
Eclipseããã¸ã§ã¯ããã¡ã¤ã«:AccountManagerOAuth2.zip (694KB)
å¤ãã®å¦çã¯tasks-android-sampleãåèã«ãã。
ããã°ã©ãã³ã°ã«å ¥ãåã«AndroidManifest.xmlã§ãã¼ããã·ã§ã³ãè¨å®ãã¦ãããªããã°ãªããªã。
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" />
ãããã®ãã¼ããã·ã§ã³ã¯å ¨ã¦å¿ è¦ã 。
ã¾ãã¯「ã¦ã¼ã¶ã¼æ å ±åå¾」ãã¿ã³ãã¯ãªãã¯ãã。ããã¨onClickBtnUserInfo()ãå¼ã³åºããã。
protected static final String AUTH_TOKEN_TYPE_PROFILE = "oauth2:https://www.googleapis.com/auth/userinfo.profile";
public void onClickBtnUserInfo(View view) {
Log.v("onClickBtnUserInfo", "ã¦ã¼ã¶ã¼æ
å ±åå¾ãã¿ã³ã¯ãªãã¯");
startRequest(AUTH_TOKEN_TYPE_PROFILE);
}
AUTH_TOKEN_TYPE_PROFILEã¯Googleã®ã¦ã¼ã¶ã¼æ å ±ãåå¾ããããã®APIã®URLã 。ãã®ã¡ã½ããã«ããstartRequest()ãå¼ã³åºããã。
protected void startRequest(String authTokenType) {
Log.v("startRequest", "ãªã¯ã¨ã¹ãéå§ - ãªã¯ã¨ã¹ãå
:" + authTokenType);
this.authTokenType = authTokenType;
if (accountName == null) {
Log.v("startRequest", "ã¢ã«ã¦ã³ãã鏿ããã¦ããªã");
chooseAccount();
} else {
getAuthToken();
}
}
èµ·åç´å¾ã¯accountNameã¯nullãªã®ã§chooseAccount()ãå¼ã³åºããã。
protected static final String ACCOUNT_TYPE = "com.google";
protected void chooseAccount() {
Log.v("chooseAccount", "AuthTokenåå¾éå§(ã¢ã«ã¦ã³ã鏿)");
accountManager.getAuthTokenByFeatures(ACCOUNT_TYPE, authTokenType, null, AccountManagerOAuth2Activity.this, null, null,
new AccountManagerCallback() {
public void run(AccountManagerFuture future) {
onGetAuthToken(future);
}
},
null);
}
accountManager.getAuthTokenByFeatures()ã¯ç«¯æ«ã«å ¥åããã¦ããã¢ã«ã¦ã³ãæ°ã«ãã£ã¦ç°ãªãåä½ããã。ä¸é£ã®ç»é¢ã¯ã¢ããªã§ã¯ãªãOSãç¨æããç»é¢ã 。
ã¢ã«ã¦ã³ããã¼ããªã、ã¢ã«ã¦ã³ãã使ããç»é¢ã«ãªã。ã¢ã«ã¦ã³ãã使ããå¾、ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã«èªå°ããã。
ã¢ã«ã¦ã³ããï¼ã¤ãªã、鏿ç»é¢ãåºãã«、ããã¢ã¯ã»ã¹è¨±å¯ç»é¢ã表示ããã。
![]() |
| ã¢ã¯ã»ã¹è¨±å¯ç»é¢ |
ããã§åé¡ãªã®ã¯、URLããã®ã¾ã¾åºã¦ãã¾ã£ã¦ãããã¨。ICS以éã ã¨åããããã説æãåºãå ´åãããããã ãã©、ãã以åã®OSã§ã¯è«¦ãããããªãããã 。
ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§AllowãDenyãããã¨onGetAuthToken()ãå¼ã³åºããã。
protected void onGetAuthToken(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
accountName = bundle.getString(AccountManager.KEY_ACCOUNT_NAME);
authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.v("onGetAuthToken", "AuthTokenåå¾å®äº accountName=" + accountName + " authToken=" + authToken + " authTokenType=" + authTokenType);
if (authTokenType.equals(AUTH_TOKEN_TYPE_PROFILE)) {
getUserInfo(); //ã¦ã¼ã¶ã¼æ
å ±åå¾éå§
} else if (authTokenType.equals(AUTH_TOKEN_TYPE_ADSENSE)) {
getAdSenseReport(); //ã¬ãã¼ãåå¾éå§
}
} catch (OperationCanceledException e) {
Log.v("onGetAuthToken", "AuthTokenåå¾ãã£ã³ã»ã«");
} catch (Exception e) {
Log.v("onGetAuthToken", "AuthTokenåå¾å¤±æ", e);
}
}
Denyããå ´åã¯future.getResult()ããæ®µéã§OperationCanceledExceptionãã¹ãã¼ããã。ã¤ã¾ããã£ã³ã»ã«æ±ã。
Allowããå ´åã¯OAuth2ã®å¦çãOSãèªåçã«è¡ã£ãçµæ、accountNameã¨authTokenãåå¾ã§ãã。ãã®å¾ã¯authTokenTypeã«è¨å®ãããå¤ã«å¾ã£ã¦getUserInfo()ãå¼ã³åºããã。
getUserInfo()ã§æ£å¸¸ã«ã¦ã¼ã¶ã¼æ å ±ãåå¾ã§ããã、次ã¯「AdSenseã¬ãã¼ãåå¾」ãã¿ã³ãã¯ãªãã¯ãã。ããã¨onClickBtnAdSense()ãå¼ã³åºããã。
protected static final String AUTH_TOKEN_TYPE_ADSENSE = "oauth2:https://www.googleapis.com/auth/adsense.readonly";
public void onClickBtnAdSense(View view) {
Log.v("onClickBtnAdSense", "AdSenseã¬ãã¼ãåå¾ãã¿ã³ã¯ãªãã¯");
startRequest(AUTH_TOKEN_TYPE_ADSENSE);
}
ããã§ã¾ãstartRequest()ãå¼ã³åºããã。ãã ã、弿°ãAUTH_TOKEN_TYPE_ADSENSEã«ãªã£ã¦ãããã¨ã«æ³¨æ。
protected void startRequest(String authTokenType) {
Log.v("startRequest", "ãªã¯ã¨ã¹ãéå§ - ãªã¯ã¨ã¹ãå
:" + authTokenType);
this.authTokenType = authTokenType;
if (accountName == null) {
Log.v("startRequest", "ã¢ã«ã¦ã³ãã鏿ããã¦ããªã");
chooseAccount();
} else {
getAuthToken();
}
}
ä»åã¯accountNameãnullã§ã¯ãªãã®ã§getAuthToken()ãå¼ã³åºããã。
protected static final int REQUEST_CODE_AUTH = 0;
protected void getAuthToken() {
Account account = null;
Account[] accounts = accountManager.getAccounts();
for (int i = 0; i < accounts.length; i++) {
account = accounts[i];
if (account.name.equals(accountName)) {
break;
}
}
Log.v("getAuthToken", "AuthTokenåå¾éå§");
accountManager.getAuthToken(account, authTokenType, true,
new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
if (bundle.containsKey(AccountManager.KEY_INTENT)) {
//ã¾ã APIã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããªãå ´åã«getAuthToken()ããã¨
//Bundleã«KEY_INTENTãå«ã¾ãã。ãã®å ´åAuthTokenã¯NULLã¨ãªã。
Log.v("getAuthToken", "ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã¸");
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
//「FLAG_ACTIVITY_NEW_TASK」ã®åã®「~」ã¯ãããå転æ¼ç®å
//ãããããªãã¨ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§ã®ãã¿ã³ã¯ãªãã¯ãå¾
ããã«onActivityResult()ãå¼ã°ãã¦ãã¾ã
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, REQUEST_CODE_AUTH);
} else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) {
onGetAuthToken(future);
}
} catch (Exception e) {
Log.v("getAuthToken", "AuthTokenåå¾å¤±æ", e);
}
}
},
null);
}
ã¾ãaccountNameããaccountãæ¤ç´¢ãã。ããã¦、ãã®accountã使ã£ã¦accountManager.getAuthToken()ãå¼ã¶。
ãã®å ã®åä½ã¯APIã®ä½¿ç¨è¨±å¯ãåºã¦ãããã©ããã§ç°ãªã。
ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããå ´åã¯、ããã«AuthTokenãåå¾ã§ããã®ã§onGetAuthToken()ãå¼ã¶。
ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããªãå ´åã¯、ããã«AuthTokenãåå¾ã§ããªãã®ã§、Intentã使ã£ã¦ã¢ã¯ã»ã¹è¨±å¯ç»é¢ãå¼ã³åºã。ä»åã¯ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããªãã®ã§ãã®ã±ã¼ã¹。
ããã§Allowããã¦ãDenyããã¦ãonActivityResult()ãå¼ã°ãã。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("onActivityResult", "requestCode=" + requestCode + " resultCode=" + resultCode);
switch (requestCode) {
case REQUEST_CODE_AUTH:
if (resultCode == RESULT_OK) {
getAuthToken();
} else {
Log.v("onActivityResult", "ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§æå¦ããã");
}
break;
}
}
ã¢ã¯ã»ã¹è¨±å¯ç»é¢ã§Allowããããæ¢åºã®getAuthToken()ãå度å¼ã³åºã。
ä»åº¦ã¯ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããã®ã§「ã¢ã¯ã»ã¹è¨±å¯ãåºã¦ããå ´å」ã«ããã、getAuthToken()å ã§æ¢åºã®onGetAuthToken()ãå¼ã°ãã。
ããã¦ä»åã¯onGetAuthToken()å ã§getAdSenseReport()ãå¼ã°ãã。
protected void getAdSenseReport() {
Log.v("getAdSenseReport", "AdSenseã¬ãã¼ãåå¾éå§");
String url = "https://www.googleapis.com/adsense/v1.1/reports"
+ "?startDate=2012-07-26"
+ "&endDate=2012-08-02"
+ "&metric=EARNINGS"
+ "&dimension=DATE"
+ "&key=" + API_KEY
+ "&access_token=" + authToken;
AsyncTaskGetJson task = new AsyncTaskGetJson();
task.setListener(new OnResultEventListener() {
@Override
public void onResult(JSONObject json) {
TextView tv = (TextView) findViewById(R.id.textView);
String msg = "";
if (json == null) {
msg = "AdSenseã¬ãã¼ãåå¾å¤±æ";
Log.v("getAdSenseReport", msg);
dialog.dismiss();
} else if (json.toString().contains(KEY_AUTH_ERROR)) {
msg = "AdSenseã¬ãã¼ãåå¾å¤±æ(èªè¨¼ã¨ã©ã¼)";
Log.v("getAdSenseReport", msg + " AuthTokenãç ´æ£ãã¦ååå¾");
accountManager.invalidateAuthToken(ACCOUNT_TYPE, authToken);
startRequest(AUTH_TOKEN_TYPE_ADSENSE);
} else {
msg = "AdSenseã¬ãã¼ãå徿å\njson=" + json.toString();
Log.v("getAdSenseReport", msg);
dialog.dismiss();
}
tv.setText(msg);
}
});
task.execute(url);
dialog.setMessage("AdSenseã¬ãã¼ãåå¾ä¸");
dialog.show();
}
authTokenã¯ä¸å®æééããã¨ç¡å¹ã«ãªãã®ã§ååå¾ããå¿ è¦ããã。
ä¸å®æéãéããauthTokenã使ã£ã¦APIã«ãªã¯ã¨ã¹ãããã¨「"code":401」ãå«ãjsonãè¿ããã。ä¸ã§ã¯「else if (json.toString().contains(KEY_AUTH_ERROR))」ã®ã±ã¼ã¹ã 。
ãã®ã±ã¼ã¹ã§ã¯accountManager.invalidateAuthToken()ããå¾startRequest()ãå度å¼ã³åºã。ããã¨æ´æ°ãããauthTokenãåå¾ã§ããããã«ãªã、ã¨ã©ã¼ç¡ããªã¯ã¨ã¹ãã§ããããã«ãªã。
以ä¸ã®ããã«ãã¦AccountManagerçµç±ã®OAuth2èªè¨¼ã§è¤æ°ã®Google APIã«ã¢ã¯ã»ã¹ã§ãã。
OAuth2ã®å¦çã«ã¤ãã¦ã¯é è½ããã¦ããã®ã§å ¨ãåãããªã。éå¸¸å¿ è¦ãªClientIDãClientSecretãå¿ è¦ãªãããã。APIã«ãªã¯ã¨ã¹ãæããæã«ã¤ãã¦ãã£ãã»ããããã®ããª?ãã®é¨åã«ã¤ãã¦ã¯ããå°ã調ã¹ãå¿ è¦ããã。





ã³ã¡ã³ã
ã³ã¡ã³ããæç¨¿