diff --git a/Changelog.md b/Changelog.md
index 83775cfc42719c70f69a83ab575783406ddae905..f6c9fe53463df752acb715091387d7dc32653ce6 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,7 @@
 
 ## Refactor
 * Background actual mailing when sending invitations [#4069](https://github.com/diaspora/diaspora/issues/4069)
+* Set the current user on the client side through gon [#4028](https://github.com/diaspora/diaspora/issues/4028)
 
 ## Bug fixes
 * Don't focus comment form on 'show n more comments' [#4265](https://github.com/diaspora/diaspora/issues/4265)
diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js
index b9f497686a0ffccd5c99715b5f7ac505173301b3..240c44f3e3096cb26526c55708373b89bb41dc81 100644
--- a/app/assets/javascripts/app/app.js
+++ b/app/assets/javascripts/app/app.js
@@ -34,7 +34,11 @@ var app = {
   initialize: function() {
     app.router = new app.Router();
 
-    app.currentUser = app.user(window.current_user_attributes) || new app.models.User()
+    if (window.gon == undefined) {
+      window.gon = {preloads:{}};
+    }
+
+    app.currentUser = app.user(window.gon.user) || new app.models.User();
 
     if(app.currentUser.authenticated()){
       app.header = new app.views.Header();
@@ -59,19 +63,19 @@ var app = {
   },
 
   hasPreload : function(prop) {
-    return !!(window.preloads && window.preloads[prop]) //returning boolean variable so that parsePreloads, which cleans up properly is used instead
+    return !!(window.gon.preloads && window.gon.preloads[prop]) //returning boolean variable so that parsePreloads, which cleans up properly is used instead
   },
 
   setPreload : function(prop, val) {
-    window.preloads = window.preloads || {}
-    window.preloads[prop] = val
+    window.gon.preloads = window.gon.preloads || {}
+    window.gon.preloads[prop] = val
   },
 
   parsePreload : function(prop){
       if(!app.hasPreload(prop)) { return }
 
-      var preload = window.preloads[prop]
-      delete window.preloads[prop] //prevent dirty state across navigates
+      var preload = window.gon.preloads[prop]
+      delete window.gon.preloads[prop] //prevent dirty state across navigates
 
       return(preload)
   },
diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js
index 4f143aa9d069d93f875ee7089a68991008144da6..0d29cd9c888f114d4d318aa1da87da1dcc78fe8a 100644
--- a/app/assets/javascripts/app/router.js
+++ b/app/assets/javascripts/app/router.js
@@ -34,7 +34,7 @@ app.Router = Backbone.Router.extend({
     post.fetch({url : window.location})
 
     function setPreloadAttributesAndNavigate(){
-      window.preloads.post = post.attributes
+      window.gon.preloads.post = post.attributes
       app.router.navigate(post.url(), {trigger:true, replace: true})
     }
   },
@@ -73,7 +73,7 @@ app.Router = Backbone.Router.extend({
     $("#tags_list").replaceWith(followedTagsView.render().el);
     followedTagsView.setupAutoSuggest();
 
-    app.tagFollowings.reset(preloads.tagFollowings);
+    app.tagFollowings.reset(gon.preloads.tagFollowings);
 
     if(name) {
       var followedTagsAction = new app.views.TagFollowingAction(
diff --git a/app/assets/javascripts/mobile.js b/app/assets/javascripts/mobile.js
index 46b2d7168b1a869d2c8c3b92b0e63f9b8dd4b949..83f787d95956a75b765f40b81d36fd21e574d2cd 100644
--- a/app/assets/javascripts/mobile.js
+++ b/app/assets/javascripts/mobile.js
@@ -276,7 +276,7 @@ $(document).ready(function(){
 
 function createUploader(){
 
-   var aspectIds = gon.aspect_ids;
+   var aspectIds = gon.preloads.aspect_ids;
 
    var uploader = new qq.FileUploaderBasic({
        element: document.getElementById('file-upload-publisher'),
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1bed2c4ade2953e7ba5c36bebe2641475b80ccbf..780852ab4b7797ed77c5e5de0f75e1b69a3d15d8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -11,6 +11,8 @@ class ApplicationController < ActionController::Base
   before_filter :set_diaspora_header
   before_filter :set_grammatical_gender
   before_filter :mobile_switch
+  before_filter :gon_set_current_user
+  before_filter :gon_set_preloads
 
   inflection_method :grammatical_gender => :gender
 
@@ -136,4 +138,17 @@ class ApplicationController < ActionController::Base
   def current_user_redirect_path
     current_user.getting_started? ? getting_started_path : stream_path
   end
+
+  def gon_set_current_user
+    return unless user_signed_in?
+    a_ids = session[:a_ids] || []
+    user = UserPresenter.new(current_user, a_ids)
+    gon.push({:user => user})
+  end
+
+  def gon_set_preloads
+    return unless gon.preloads.nil?
+    gon.preloads = {}
+  end
+
 end
diff --git a/app/controllers/streams_controller.rb b/app/controllers/streams_controller.rb
index 7c4484f512cfb38ce5a9573c0de7d06f821ce3cd..6ce788a17b11668320dc56663a7d59237f0b28c8 100644
--- a/app/controllers/streams_controller.rb
+++ b/app/controllers/streams_controller.rb
@@ -43,7 +43,7 @@ class StreamsController < ApplicationController
   end
 
   def followed_tags
-    gon.tagFollowings = tags
+    gon.preloads[:tagFollowings] = tags
     stream_responder(Stream::FollowedTag)
   end
 
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 2729268efdde4deaf484b770ab8a1ac326ddb190..86b095975fe23e48bcf3effd83afd0b3022065aa 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -33,7 +33,7 @@ class TagsController < ApplicationController
     redirect_to(:action => :show, :name => downcased_tag_name) && return if tag_has_capitals?
 
     if user_signed_in?
-      gon.tagFollowings = tags
+      gon.preloads[:tagFollowings] = tags
     end
     @stream = Stream::Tag.new(current_user, params[:name], :max_time => max_time, :page => params[:page])
     respond_with do |format|
diff --git a/app/helpers/layout_helper.rb b/app/helpers/layout_helper.rb
index d29b1243ebe4bb17f4d386b405012e96164f3bbd..3b7c716acf2ddd9250d71f2693016f1d853a0a83 100644
--- a/app/helpers/layout_helper.rb
+++ b/app/helpers/layout_helper.rb
@@ -37,17 +37,6 @@ module LayoutHelper
     end
   end
 
-  def set_current_user_in_javascript
-    return unless user_signed_in?
-    a_ids = session[:a_ids] || []
-    user = UserPresenter.new(current_user, a_ids).to_json
-    content_tag(:script) do
-      <<-JS.html_safe
-        window.current_user_attributes = #{j user}
-      JS
-    end
-  end
-
   def current_user_atom_tag
     return #temp hax
 
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index d5750f4b7a48dee57f63dec38d45ee8934ba4e33..fb788d0a169921e4e4e0851a34dad56b43aef9f6 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -43,7 +43,6 @@
       = load_javascript_locales
 
     = set_asset_host
-    = set_current_user_in_javascript
     = translation_missing_warnings
     = current_user_atom_tag
 
@@ -54,7 +53,7 @@
       %link{:rel => 'alternate', :type => "application/json+oembed", :href => "#{oembed_url(:url => post_url(@post))}"}
       = og_page_specific_tags(@post)
 
-    = include_gon(:camel_case => true, :namespace => :preloads)
+    = include_gon(:camel_case => true)
 
   %body
     = flash_messages
diff --git a/spec/helpers/layout_helper_spec.rb b/spec/helpers/layout_helper_spec.rb
index f1bba1c7f8ed1151cab293319323dc3a356dea91..33b3ae2e1879f05756afcb671790776513f50f5e 100644
--- a/spec/helpers/layout_helper_spec.rb
+++ b/spec/helpers/layout_helper_spec.rb
@@ -5,18 +5,6 @@
 require 'spec_helper'
 
 describe LayoutHelper do
-  describe "#set_current_user_in_javascript" do
-    it "doesn't allow xss" do
-      user = FactoryGirl.create :user
-      profile = user.profile
-      profile.update_attribute(:first_name, "</script><script>alert(0);</script>");
-      stub!(:user_signed_in?).and_return true
-      stub!(:current_user).and_return user
-      set_current_user_in_javascript.should_not be_empty
-      set_current_user_in_javascript.should_not include(profile.first_name)
-    end
-  end
-
   describe "#page_title" do
     context "passed blank text" do
       it "returns Diaspora*" do
diff --git a/spec/javascripts/app/views/post/small_frame_view_spec.js b/spec/javascripts/app/views/post/small_frame_view_spec.js
index d6b83e36d706fb99e4a9df319bf8df4b9f52bfd7..c4e022cb1fb19e08f17b276131b589103e5e2674 100644
--- a/spec/javascripts/app/views/post/small_frame_view_spec.js
+++ b/spec/javascripts/app/views/post/small_frame_view_spec.js
@@ -40,7 +40,7 @@ describe("app.views.Post.SmallFrame", function(){
     beforeEach(function(){
       app.page = { editMode : false }
       app.router = new app.Router()
-      window.preloads = {}
+      window.gon.preloads = {}
       spyOn(app.router, "navigate")
     })