{"id":773,"date":"2020-05-04T22:54:38","date_gmt":"2020-05-04T13:54:38","guid":{"rendered":"https:\/\/www.typea.info\/blog\/?p=773"},"modified":"2020-10-31T00:06:20","modified_gmt":"2020-10-30T15:06:20","slug":"flutter-firebase-auth-twitter-signin","status":"publish","type":"post","link":"https:\/\/www.typea.info\/blog\/index.php\/2020\/05\/04\/flutter-firebase-auth-twitter-signin\/","title":{"rendered":"Flutter: Firebase auth \u304b\u3089 twitter \u30b5\u30a4\u30f3\u30a4\u30f3\u3092\u884c\u3046\u3002Android\u3068iPhone"},"content":{"rendered":"<p><a href=\"https:\/\/www.amazon.co.jp\/%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AC%E3%82%B9%E9%96%8B%E7%99%BA%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0-Firebase%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0%E6%B4%A5%E8%80%B6%E4%B9%83-ebook\/dp\/B07X5FR7XR\/ref=as_li_ss_il?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;dchild=1&amp;keywords=Firebase&amp;qid=1588598826&amp;sr=8-3&amp;linkCode=li2&amp;tag=typea09-22&amp;linkId=feb8fa4e2f7dbba9e54ed09ebfbb425b&amp;language=ja_JP\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"\/\/ws-fe.amazon-adsystem.com\/widgets\/q?_encoding=UTF8&amp;ASIN=B07X5FR7XR&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=JP&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=typea09-22&amp;language=ja_JP\" border=\"0\"><\/a><img loading=\"lazy\" decoding=\"async\" width=\"1\" height=\"1\" style=\"margin: 0px !important; border: currentcolor !important; border-image: none !important !important;\" alt=\"\" src=\"https:\/\/ir-jp.amazon-adsystem.com\/e\/ir?t=typea09-22&amp;language=ja_JP&amp;l=li2&amp;o=9&amp;a=B07X5FR7XR\" border=\"0\"><\/p>\n<h2><\/h2>\n<h2>1.\u306a\u304c\u308c<\/h2>\n<p><a href=\"https:\/\/www.typea.info\/blog\/index.php\/category\/flutter\/\">Flutter\u30a2\u30d7\u30ea\u7528\u306e\u90e8\u54c1\u96c6\u3081<\/a>\u3001<a href=\"https:\/\/www.typea.info\/blog\/index.php\/category\/firebase\/\">\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u3001Firebase\u3092\u4f7f\u7528\u3059\u308b<\/a>\u3002<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/05\/03\/flutter-google-sign-in-android-ios\/\">Google \u30b5\u30a4\u30f3\u30a4\u30f3\u3092\u5b9f\u73fe\u3057\u305f<\/a>\u306e\u3067\u3001twitter\u3092\u8a66\u3059\u3002<\/p>\n<p><a href=\"https:\/\/pub.dev\/packages\/firebase_auth\">firebase_auth \u30d7\u30e9\u30b0\u30a4\u30f3<\/a> \u3067\u5168\u90e8\u884c\u3051\u308b\u304b\u3068\u601d\u3063\u305f\u3089\u3001Firebase\u306b\u304b\u304b\u308b\u90e8\u5206\u306e\u307f\u3067\u3001twitter\u304b\u3089\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u3092\u3082\u3089\u3046\u3042\u305f\u308a\u306e\u51e6\u7406\u306f\u7bc4\u56f2\u5916\u306e\u3088\u3046\u3002<\/p>\n<p><a href=\"https:\/\/pub.dev\/packages\/flutter_twitter_login\">flutter_twitter_login \u30d7\u30e9\u30b0\u30a4\u30f3<\/a>\u3092\u8a66\u3057\u305f\u304c\u3001\u5185\u90e8\u3067\u975e\u63a8\u5968\u306ejava api\u3092\u5229\u7528\u3057\u3066\u3044\u308b\u3068\u3044\u3046\u30ed\u30b0\u304c\u51fa\u308b\u3053\u3068\u3068\u3001\u516c\u5f0f\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u306a\u3044\u3053\u3068\u304b\u3089\u3001\u5bfe\u51e6\u3092\u30b0\u30b0\u308b\u4e2d\u3067\u3001<a href=\"https:\/\/stackoverflow.com\/questions\/60461547\/how-to-sign-in-with-twitter-using-firebase-auth-with-flutter\">Stackoverflow\u306e\u30b3\u30e1\u30f3\u30c8<\/a>\u3092\u53c2\u8003\u306b\u51e6\u7406\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3068\u3059\u308b\u3002<\/p>\n<p>\u52d5\u3044\u305f\u3068\u3053\u308d(Android\/iPhone)<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/D58o6kWbedk\" frameborder=\"0\" allowfullscreen=\"\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"><\/iframe><\/p>\n<h2>2.\u6e96\u5099<\/h2>\n<h3>2.1 twitter<\/h3>\n<p>\u4ee5\u4e0b\u306e\u30b5\u30a4\u30c8\u304b\u3089\u3001\u30a2\u30d7\u30ea\u306e\u767b\u9332\u3092\u884c\u3044\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8a73\u7d30 \u2013 Key and Tokens \u304b\u3089\u3001API key \u3068 API secret key \u3092\u767a\u884c\u3059\u308b\u3002<\/p>\n<h3><a href=\"https:\/\/developer.twitter.com\/en\">Twitter Developer<\/a><\/h3>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_dev_api_key.png\"><img loading=\"lazy\" decoding=\"async\" width=\"620\" height=\"256\" title=\"twitter_dev_api_key\" style=\"display: inline; background-image: none;\" alt=\"twitter_dev_api_key\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_dev_api_key_thumb.png\" border=\"0\"><\/a><\/p>\n<h3>2.2 Firebase Console<\/h3>\n<p>Firebase\u304c\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u3057\u3066\u3001\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u5148\u306eURL\u3084\u3089\u3092\u6e96\u5099\u3057\u3066\u304f\u308c\u308b\u3002<\/p>\n<p>\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304b\u3089\u3001Authentication \u3001Sign in method \u304b\u3089 twitter \u3092\u9078\u629e<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_firebase_auth01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"331\" title=\"twitter_firebase_auth01\" style=\"display: inline; background-image: none;\" alt=\"twitter_firebase_auth01\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_firebase_auth01_thumb.png\" border=\"0\"><\/a><\/p>\n<p>2.1\u3067\u53d6\u5f97\u3057\u305f\u3001API Key \u3068 API secret&nbsp; key \u3092\u767b\u9332\u3001\u6709\u52b9\u306b\u3059\u308b\u3002<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_firebase_auth02.png\"><img loading=\"lazy\" decoding=\"async\" width=\"556\" height=\"278\" title=\"twitter_firebase_auth02\" style=\"display: inline; background-image: none;\" alt=\"twitter_firebase_auth02\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_firebase_auth02_thumb.png\" border=\"0\"><\/a><\/p>\n<h2><\/h2>\n<h2>3.\u5b9f\u88c5<\/h2>\n<h3>3.1 \u547c\u3073\u51fa\u3057\u5074<\/h3>\n<ol>\n<li>Tiwtter Sign In \u30dc\u30bf\u30f3\u62bc\u4e0b\u3067\u3001\u4e0a\u8a182\u3067\u53d6\u5f97\u3057\u305fAPI\u30ad\u30fc\u3092\u3001TwitterSiginInPage\u306b\u5f15\u304d\u6e21\u3059<\/li>\n<li>\u753b\u9762\u9077\u79fb\u3092\u7d42\u3048\u3001\u623b\u3063\u3066\u304f\u308b\u3068\u3001credential \u306b\u3001\u30c8\u30fc\u30af\u30f3\u304c\u542b\u307e\u308c\u3066\u3044\u308b<\/li>\n<li>\u53d6\u5f97\u3057\u305f\u30c8\u30fc\u30af\u30f3\u3092Firebase auth\u306b\u6e21\u3057\u3066\u3001\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u3092\u53d6\u5f97\u3057\u753b\u9762\u8868\u793a<\/li>\n<\/ol>\n<h3>lib\\firebase_auth.dart<\/h3>\n<pre class=\"prettyprint\">import 'dart:io';\nimport 'package:flutter\/cupertino.dart';\nimport 'package:flutter\/material.dart';\nimport 'package:firebase_auth\/firebase_auth.dart';\n\nimport '.\/twitter_sign_in.dart';\n\nclass FirebaseAuthPage extends StatefulWidget {\n  @override\n  State&lt;StatefulWidget&gt; createState() =&gt; FIrebaseAuthPageState();\n}\n\nenum Menu {\n  twitter_sign_in,\n  item2,\n}\nclass FIrebaseAuthPageState extends State&lt;FirebaseAuthPage&gt; {\n  final FirebaseAuth _auth = FirebaseAuth.instance;\n  String _userAvatarUrl = '';\n  String _userDisplayName = '';\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Firebase Auth Sample\"),\n      ),\n      body: Column(\n        children: &lt;Widget&gt;[\n          PopupMenuButton(\n            onSelected: popupMenuSelected,\n            itemBuilder: (BuildContext context) =&gt;\n            &lt;PopupMenuEntry&lt;Menu&gt;&gt;[\n              const PopupMenuItem( child: const ListTile( leading:Icon(Icons.account_box),\n                  title:Text(\"Twitter Sign In\")), value: Menu.twitter_sign_in),\n              const PopupMenuItem( child: const ListTile( leading:Icon(Icons.account_circle),\n                  title:Text(\"item2\")), value: Menu.item2),\n            ],\n          ),\n          ListTile(leading :\n            CircleAvatar(\n              backgroundImage: NetworkImage(_userAvatarUrl),\n            ),\n            title:Text(_userDisplayName ?? ''),),\n        ],\n      ),\n    );\n  }\n  void popupMenuSelected(Menu selectedMenu){\n    switch(selectedMenu) {\n      case Menu.twitter_sign_in:\n        _pushTwitterPage(context);\n        break;\n      default:\n        break;\n    }\n  }\n\n  void _pushTwitterPage(BuildContext context) async {\n    Widget page = TwitterSignInPage(\n            consumerKey: \"***** your api key ****\",\n            consumerSecret: \"***** your api secret key ****\",\n            oauthCallbackHandler: \"https:\/\/**** firebase call back url ****\");\n\n    final credential = await Navigator.of(context).push(\n        MaterialPageRoute&lt;AuthCredential&gt;(builder: (_) =&gt; page)\n    );\n\n    FirebaseUser user;\n    if (credential != null) {\n      user = (await _auth.signInWithCredential(credential)).user;\n    }\n    setState(() {\n      if (user != null) {\n        _userAvatarUrl = user.photoUrl;\n        _userDisplayName = user.displayName;\n      } else {\n        _userDisplayName = 'Failed to sign in with Twitter. ';\n      }\n    });\n  }\n\n\/\/  void _twitterSignOut() async {\n\/\/    _auth.signOut();\n\/\/  }\n\n}<\/pre>\n<h3>3.2 twitter \u30ed\u30b0\u30a4\u30f3\u4e3b\u51e6\u7406<\/h3>\n<p>5\u5e74\u307b\u3069\u524d<a href=\"https:\/\/www.typea.info\/blog\/index.php\/2015\/05\/06\/django_python-twitter_oauth_twitter_api\/\">5\u5e74\u307b\u3069\u524d\u306b\u3082\u3001Django\u3067\u540c\u3058\u3053\u3068\u3092\u3084\u3063\u3066\u3044\u305f<\/a>\u3002\u4ee5\u4e0b\u3092\u53c2\u8003\u306bSTEP1~3\u3092\u5b9f\u88c5<\/p>\n<p><a title=\"https:\/\/stackoverflow.com\/questions\/60461547\/how-to-sign-in-with-twitter-using-firebase-auth-with-flutter\" href=\"https:\/\/stackoverflow.com\/questions\/60461547\/how-to-sign-in-with-twitter-using-firebase-auth-with-flutter\">https:\/\/stackoverflow.com\/questions\/60461547\/how-to-sign-in-with-twitter-using-firebase-auth-with-flutter<\/a><\/p>\n<p><a href=\"https:\/\/developer.twitter.com\/en\/docs\/basics\/authentication\/guides\/log-in-with-twitter\">Login with twitter \u30ac\u30a4\u30c9<\/a><\/p>\n<h3>STEP1<\/h3>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism.png\"><img loading=\"lazy\" decoding=\"async\" width=\"476\" height=\"277\" title=\"twitter_login_mechanism\" style=\"display: inline; background-image: none;\" alt=\"twitter_login_mechanism\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism_thumb.png\" border=\"0\"><\/a><\/p>\n<h3>STEP2<\/h3>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism_step2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"482\" height=\"325\" title=\"twitter_login_mechanism_step2\" style=\"display: inline; background-image: none;\" alt=\"twitter_login_mechanism_step2\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism_step2_thumb.png\" border=\"0\"><\/a><\/p>\n<h3>STEP3<\/h3>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism_step3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"484\" height=\"286\" title=\"twitter_login_mechanism_step3\" style=\"display: inline; background-image: none;\" alt=\"twitter_login_mechanism_step3\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/05\/twitter_login_mechanism_step3_thumb.png\" border=\"0\"><\/a><\/p>\n<h3>lib\/twitter_sign_in.dart<\/h3>\n<pre class=\"prettyprint\">import 'package:flutter\/cupertino.dart';\nimport 'package:flutter\/material.dart';\nimport 'package:flutter_webview_plugin\/flutter_webview_plugin.dart';\nimport 'package:oauth1\/oauth1.dart';\nimport 'package:firebase_auth\/firebase_auth.dart';\n\n\/\/\/\n\/\/\/ https:\/\/stackoverflow.com\/questions\/60461547\/how-to-sign-in-with-twitter-using-firebase-auth-with-flutter\n\/\/\/\nclass TwitterSignInPage extends StatefulWidget {\n\n  final twitterPlatform = Platform(\n    'https:\/\/api.twitter.com\/oauth\/request_token', \/\/ temporary credentials request\n    'https:\/\/api.twitter.com\/oauth\/authorize', \/\/ resource owner authorization\n    'https:\/\/api.twitter.com\/oauth\/access_token', \/\/ token credentials request\n    SignatureMethods.hmacSha1, \/\/ signature method\n  );\n\n  final ClientCredentials clientCredentials;\n  final String oauthCallbackHandler;\n\n  TwitterSignInPage({\n    @required final String consumerKey,\n    @required final String consumerSecret,\n    @required this.oauthCallbackHandler,\n  }) : clientCredentials = ClientCredentials(consumerKey, consumerSecret);\n\n  @override\n  State&lt;StatefulWidget&gt; createState() =&gt; TwitterSignInPageState();\n}\n\nenum Menu {twitter_sign_in, twitter_sign_out}\n\nclass TwitterSignInPageState extends State&lt;TwitterSignInPage&gt; {\n  final flutterWebviewPlugin = FlutterWebviewPlugin();\n\n  Authorization _oauth;\n\n  @override\n  void initState() {\n    super.initState();\n\n    \/\/ Twitter OAuth \u306e\u521d\u671f\u5316\n    _oauth = Authorization(widget.clientCredentials, widget.twitterPlatform);\n\n    flutterWebviewPlugin.onUrlChanged.listen((url) {\n      \/\/ STEP2\u306e\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3092\u3001STEP3\u3078\u79fb\u52d5\u3059\u308b\u305f\u3081\u306b\u76e3\u8996\n      if (url.startsWith(widget.oauthCallbackHandler)) {\n        final queryParameters = Uri.parse(url).queryParameters;\n        final oauthToken = queryParameters['oauth_token'];\n        final oauthVerifier = queryParameters['oauth_verifier'];\n        if (null != oauthToken &amp;&amp; null != oauthVerifier) {\n          _twitterLogInFinish(oauthToken, oauthVerifier);\n        }\n      }\n    });\n    _twitterLogInStart();\n  }\n\n  @override\n  void dispose() {\n    flutterWebviewPlugin.dispose();\n    super.dispose();\n  }\n\n  Future&lt;void&gt; _twitterLogInStart() async {\n    assert(null != _oauth);\n\n    \/\/ STEP1:\u30ea\u30af\u30a8\u30b9\u30c8\u30c8\u30fc\u30af\u30f3\u306e\u5165\u624b\n    \/\/    oauth\/request_token\u3092POST\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u30c8\u30fc\u30af\u30f3\u3092\u5165\u624b\n    \/\/    oauth_callback\u306f\u3001STEP2\u304c\u6210\u529f\u3057\u305f\u3068\u304d\u306b\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u3055\u308c\u308bURL\n    final requestTokenResponse =\n        await _oauth.requestTemporaryCredentials(widget.oauthCallbackHandler);\n\n    \/\/ STEP2: \u8a8d\u8a3c\u30da\u30fc\u30b8\u3078\u306e\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\n    \/\/   oauth\/authenticate \u306eGET\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u3001STEP1\u3067\u5165\u624b\u3057\u305f\u30c8\u30fc\u30af\u30f3\u3092\u3001oauth_token\u3068\u3057\u3066\u6e21\u3059\n    final authorizationPage = _oauth.getResourceOwnerAuthorizationURI(\n        requestTokenResponse.credentials.token);\n\n    flutterWebviewPlugin.reloadUrl(authorizationPage);\n  }\n\n  Future&lt;void&gt; _twitterLogInFinish(\n      String oauthToken, String oauthVerifier) async {\n\n    \/\/ STEP3: \u30ea\u30af\u30a8\u30b9\u30c8\u30c8\u30fc\u30af\u30f3\u3092\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306b\u5909\u63db\n    \/\/     \u30ea\u30af\u30a8\u30b9\u30c8\u30c8\u30fc\u30af\u30f3\u3092\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306b\u66f8\u63db\u3048\u308b\u306e\u306b\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306fPOST oauth\/access_token \u3078 STEP2\u3067\u5165\u624b\u3057\u305f\u3001\n    \/\/     oauth_verifier POST\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u4fe1\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\n    \/\/     \u30ea\u30af\u30a8\u30b9\u30c8\u30c8\u30fc\u30af\u30f3\u306f\u3001oauth_token \u30d8\u30c3\u30c0\u30fc\u306b\u3082\u6e21\u3055\u308c\u308b\u304c\u3001\u3053\u308c\u306f\u7f72\u540d\u30d7\u30ed\u30bb\u30b9\u306b\u8ffd\u8a18\u3055\u308c\u308b\n    final tokenCredentialsResponse = await _oauth.requestTokenCredentials(\n        Credentials(oauthToken, ''), oauthVerifier);\n\n    final result = TwitterAuthProvider.getCredential(\n      authToken: tokenCredentialsResponse.credentials.token,\n      authTokenSecret: tokenCredentialsResponse.credentials.tokenSecret,\n    );\n    print(\"result $result\");\n\n    Navigator.pop(context, result);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return WebviewScaffold(\n      appBar: AppBar(title: Text(\"Twitter Login\")),\n      url: \"https:\/\/twitter.com\",\n    );\n  }\n}<\/pre>\n<p>\u4ee5\u4e0a\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1.\u306a\u304c\u308c Flutter\u30a2\u30d7\u30ea\u7528\u306e\u90e8\u54c1\u96c6\u3081\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u3001Firebase\u3092\u4f7f\u7528\u3059\u308b\u3002 Google \u30b5\u30a4\u30f3\u30a4\u30f3\u3092\u5b9f\u73fe\u3057\u305f\u306e\u3067\u3001twitter\u3092\u8a66\u3059\u3002 firebase_auth \u30d7\u30e9\u30b0\u30a4\u30f3 \u3067\u5168\u90e8\u884c\u3051\u308b\u304b\u3068\u601d\u3063\u305f\u3089 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":917,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","sitemap_hide":"","_veu_custom_css":"","veu_display_promotion_alert":"","vkexunit_cta_each_option":"","footnotes":""},"categories":[104,111,82],"tags":[],"class_list":["post-773","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-firebase","category-flutter","category-twitter"],"veu_head_title_object":{"title":"","add_site_title":""},"_links":{"self":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/773","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=773"}],"version-history":[{"count":4,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/773\/revisions"}],"predecessor-version":[{"id":926,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/773\/revisions\/926"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/media\/917"}],"wp:attachment":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}