{"id":51788,"date":"2016-09-22T14:41:38","date_gmt":"2016-09-22T14:41:38","guid":{"rendered":"http:\/\/barrycarlyon.co.uk\/wordpress\/?p=51788"},"modified":"2016-09-22T14:43:45","modified_gmt":"2016-09-22T14:43:45","slug":"google-oauth-and-offline-access","status":"publish","type":"post","link":"https:\/\/barrycarlyon.co.uk\/wordpress\/2016\/09\/22\/google-oauth-and-offline-access\/","title":{"rendered":"Google oAuth and offline access"},"content":{"rendered":"<p>Been doing a lot of various stuff and things for <a href=\"https:\/\/www.twitch.tv\/cohhcarnage\">CohhCarnage<\/a> and some of that stuff has involved building an achievements tracking system for the <a href=\"https:\/\/www.cohhilition.com\/achievements\/\">website<\/a>.<\/p>\n<p>One of those achievements, is for YouTube Subscription. Where the achievement is awarded to the logged in user, if the user has subscribed to a given YouTube channel, in this case <a href=\"http:\/\/www.youtube.com\/CohhCarnage\/\">Cohh&#8217;s YouTube<\/a>.<\/p>\n<p>In order to make sure that people can&#8217;t &#8220;cheat&#8221; the system, we ask them to link their Google\/YouTube account with the website and use the relevant API to look up their Subscription status.<\/p>\n<p>Initially this worked fine, but I ran into some issues where the oAuth token stored has expired and thus I can&#8217;t do a status check, for cases where the user links their YouTube to their Cohhilition Account then doesn&#8217;t subscribe on YouTube until after 24 hours later (or some caching issue with Google).<\/p>\n<p>So, the simple fix using Googles PHP Library for oAuth&#8217;ing is to just do a<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\r\n$client-&gt;setAccessType('offline')\r\n\r\n<\/pre>\n<p>Now, this works fine for the most part, you happily get a refresh token, and can thus renew your token.<\/p>\n<p>Then comes a hiccup, if for whatever reason you have offline access type on, and the user has previously authorised the application and it&#8217;s offline permission, you <strong>DON&#8217;T<\/strong> get a refresh token in some cases. Some user cases include:<\/p>\n<ul>\n<li>you&#8217;ve lost their token,<\/li>\n<li>or got a bad one<\/li>\n<li>or the user managed to find the authentication loop (again) when they shouldn&#8217;t, and thus a new code\/token combo is generated<\/li>\n<\/ul>\n<p>Normally you are using something like:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\r\n$client = new Google_Client();\r\n$client-&gt;setClientId($client_id);\r\n$client-&gt;setClientSecret($client_secret);\r\n$client-&gt;setRedirectUri($redirect_uri);\r\n$client-&gt;addScope(&quot;email&quot;);\r\n$client-&gt;addScope(&quot;profile&quot;); \r\n$client-&gt;setAccessType('offline');\/\/ last forever\/give me a refresh\r\n\r\n<\/pre>\n<p>But in order to make sure that you get a refresh_token EVERY time someone goes through the authentication loop, you have to adjust as follows:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\r\n$client = new Google_Client();\r\n$client-&gt;setClientId($client_id);\r\n$client-&gt;setClientSecret($client_secret);\r\n$client-&gt;setRedirectUri($redirect_uri);\r\n$client-&gt;addScope(&quot;email&quot;);\r\n$client-&gt;addScope(&quot;profile&quot;); \r\n$client-&gt;setAccessType('offline');\/\/ last forever\/give me a refresh\r\n$client-&gt;setApprovalPrompt('force');\/\/ force a refresh token return everytime\r\n\r\n<\/pre>\n<p>Apparently, using<\/p>\n<pre>'offline'<\/pre>\n<p>is supposed to imply<\/p>\n<pre>'force'<\/pre>\n<p>according to some Stack Overflows posts, but this doesn&#8217;t seem the case.<\/p>\n<p>In the end my full Google_Client setup looks like:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\r\n        $client = new Google_Client();\r\n        $client-&gt;setAuthConfig($consumer);\r\n        $client-&gt;addScope('profile');\r\n        $client-&gt;addScope('email');\r\n        $client-&gt;addScope('https:\/\/www.googleapis.com\/auth\/youtube.readonly');\r\n        $client-&gt;setAccessType('offline');\/\/ asks for a refresh token\r\n        $client-&gt;setApprovalPrompt('force');\/\/ forces the refresh token being returned\r\n        $client-&gt;setIncludeGrantedScopes(true);\r\n        $client-&gt;setRedirectUri($callback);\r\n\r\n<\/pre>\n<p>Just an odd thing I came across recently that I thought I would write up. Most of the notes here are from <a href=\"http:\/\/stackoverflow.com\/questions\/10827920\/not-receiving-google-oauth-refresh-token\">Stack Overflow post on the subject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Been doing a lot of various stuff and things for CohhCarnage and some of that stuff has involved building an achievements tracking system for the website. One of those achievements, is for YouTube Subscription. Where the achievement is awarded to the logged in user, if the user has subscribed to a given YouTube channel, in &hellip; <a href=\"https:\/\/barrycarlyon.co.uk\/wordpress\/2016\/09\/22\/google-oauth-and-offline-access\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Google oAuth and offline access&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[88,198,45,27],"tags":[82,336,171,338,84,337,339],"class_list":["post-51788","post","type-post","status-publish","format-standard","hentry","category-code-geekery","category-code-snippets","category-geekery","category-work","tag-code","tag-google-api","tag-oauth","tag-offline_access","tag-php","tag-refresh_token","tag-stack-overflow"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51788","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/comments?post=51788"}],"version-history":[{"count":6,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51788\/revisions"}],"predecessor-version":[{"id":51794,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51788\/revisions\/51794"}],"wp:attachment":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/media?parent=51788"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/categories?post=51788"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/tags?post=51788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}