{"id":1044,"date":"2012-02-11T20:33:24","date_gmt":"2012-02-12T01:33:24","guid":{"rendered":"http:\/\/yuguangzhang.com\/blog\/?p=1044"},"modified":"2012-02-11T20:33:24","modified_gmt":"2012-02-12T01:33:24","slug":"course-planner-authentication-libraries","status":"publish","type":"post","link":"http:\/\/yuguangzhang.com\/blog\/course-planner-authentication-libraries\/","title":{"rendered":"Course Planner Authentication Libraries"},"content":{"rendered":"<p>Just working on this project yesterday, I discovered the Facebook login was no longer working. I noticed from my other projects Facebook changed their API and the library needed to be upgraded. \u00a0Back in 2009, the best library available was <a href=\"http:\/\/agiliq.com\/blog\/2009\/08\/django-socialauth-login-via-twitter-facebook-openi\/\">socialauth<\/a>. Now I&#8217;m using <a href=\"https:\/\/github.com\/omab\/django-social-auth\">social_auth<\/a> in my newer projects. There&#8217;s more documentation at first glance. Although problems showed up from time to time, upgrading always fixed them. So I would recommend <a href=\"https:\/\/github.com\/omab\/django-social-auth\">social_auth<\/a>.<\/p>\n<p>It turns out I could use an independent login module, already a part of the shared codebase for 2 other projects, at a cost. The cost is to add the login button to keep the logic flow the same. Later, I used a <a href=\"http:\/\/www.knockmeout.net\/2011\/03\/reacting-to-changes-in-knockoutjs.html\">dependent observable<\/a> to automatically save after the authentication state changes. Simply pass the load or save function as an argument to the login decorator (Python term, same concept in JavaScript):<\/p>\n<p>[cc lang=&#8221;javascript&#8221;]<\/p>\n<p>loginRequired: function (action) {<br \/>\n        if (viewModel.authenticated()) {<br \/>\n            return false;<br \/>\n        } else {<br \/>\n            viewModel.setMessage(loginPrompt, &#8216;warning&#8217;);<br \/>\n            viewModel.afterLogin = action;<br \/>\n            return true;<br \/>\n        }<br \/>\n    },<\/p>\n<p>[\/cc]<br \/>\nThe save function begins by checking if the user is logged in:<br \/>\n[cc lang=&#8221;javascript&#8221;]<br \/>\nsave: function () {<br \/>\n        if (viewModel.loginRequired(viewModel.save)) return;<br \/>\n[\/cc]<br \/>\n<em>afterLogin<\/em> is called in the observable:<br \/>\n[cc lang=&#8221;javascript&#8221;]<br \/>\nko.dependentObservable(function() {<br \/>\n    if (viewModel.authenticated() &#038;&#038; viewModel.message() == loginPrompt) {<br \/>\n        viewModel.setMessage(&#8221;);<br \/>\n        viewModel.afterLogin();<br \/>\n    }<br \/>\n});<br \/>\n[\/cc]<br \/>\nAfter a hectic few minutes of upgrading the site with about 3 different kinds of server errors and many email debug messages, I finished upgrading the database and the settings file.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/yuguangzhang.com\/blog\/wp-content\/uploads\/2012\/02\/screenshot.4-300x216.png\" alt=\"\" title=\"screenshot.4\" width=\"300\" height=\"216\" class=\"aligncenter size-medium wp-image-1045\" srcset=\"http:\/\/yuguangzhang.com\/blog\/wp-content\/uploads\/2012\/02\/screenshot.4-300x216.png 300w, http:\/\/yuguangzhang.com\/blog\/wp-content\/uploads\/2012\/02\/screenshot.4.png 789w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><br \/>\nMaybe next time I will use if DEBUG statements in my settings file so it can be copied straight to server. But the main reason I opted not to was because of the facebook, twitter, and google keys which had to be set differently. On the other hand, those can be in a conditional debug statement, too.<br \/>\nOverall, it was a thrill to work with the project again, bring back the gifts from more recent projects, and see the brilliantly written code. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just working on this project yesterday, I discovered the Facebook login was no longer working. I noticed from my other projects Facebook changed their API and the library needed to be upgraded. \u00a0Back in 2009, the best library available was socialauth. Now I&#8217;m using social_auth in my newer projects. There&#8217;s more documentation at first glance. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[29,23],"tags":[133,157,158,160,159],"class_list":["post-1044","post","type-post","status-publish","format-standard","hentry","category-coursetree","category-programming","tag-javascript","tag-knockout","tag-mvc","tag-social-authentication","tag-system-administration"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts\/1044","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/comments?post=1044"}],"version-history":[{"count":0,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts\/1044\/revisions"}],"wp:attachment":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/media?parent=1044"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/categories?post=1044"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/tags?post=1044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}