Skip to content

Error: origin_mismatch when using Google OAuth on a non-localhost domain

Not developing on localhost? Google’s “Authorized JavaScript origins” list can only be configured to use localhost:port (e.g. http://localhost:3000) for development. This poses an annoying problem for those of us that are developing remotely or with a VM.

My current setup has me running a Ubuntu VM using VirtualBox, on a Windows 10 host. Since the disks are shared, I run my IDE on Windows, and use a browser in Windows to point to my VM (e.g. http://192.168.1.10:3000). Google doesn’t like this, and keeps giving me an “origin_mismatch” error when I try to use Google OAuth on this domain.

I’ve tried multiple workarounds, and this is what I found to work:

1. Edit your host file in windows

Open notepad using administrator privilege, and open C:\Windows\System32\drivers\etc\hosts
Add the line `192.168.1.10 www.mysite-dev.com` (or whatever IP your VM/remote server has)

2. Flush DNS

Open command prompt
Run `ipconfig /flushdns`

3. Restart your webserver to use port 80 (or 433 if you’re using ssl)

If you’re using Rails, you can use `thin` to run an ssl server. Otherwise, just use `rails server -p 80`.
If you run into permission errors like I did, prefix your commands with `sudo`. (or `rvmsudo` you’re using RVM)

4. Navigate your browser to `http://www.mysite-dev.com` or `https://www.mysite-dev.com` to make sure it loads
5. Once it loads, update your Google Authorized JavaScript origins to include the above url
6. Try logging in with Google OAuth in your project!

Error when installing fcgi gem

If you’re getting this error when installing fcgi:

Installing fcgi 0.9.2.1 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

you need to actually install FastCGI first. (`gem install fcgi` just installs the ruby bindings)

Normally, `brew install fcgi` would be ok, but it looks like the fcgi library has been taken down. Instead, download the source and built it yourself:

Download link: https://www.dropbox.com/s/hlg5vv1rb90suid/fcgi-2.4.0.tar.gz?dl=0

Then run:

tar xzvf fcgi-2.4.0.tar.gz
cd fcgi-2.4.0
./configure –prefix=/usr/local
sudo make
sudo make install

Great, now that fcgi is installed, go install the actual gem (via `bundle install` or otherwise)

Easy Rails deployment with rsync

Starting a new Rails app? I find one of the most annoying thing with writing code is the initial deployment. I just want to get my little app online! The fastest way to deploy Rails (or any) code to production is probably rsync.

rsync is actually a tool used to keep files synchronized, by copying/deleting the files that changed. Turns out, it’s a pretty handy way to deploy code too!

 

Deployment steps:
(in your localhost, cd’d into your development branch)

$ cd my-rails-app

 

Compile your assets locally. You can choose to run this on your production server as well, but I prefer to do it here for small applications using a weak production server.

$ bundle exec rake assets:precompile

 

Run rsync to copy your local files over to your production machine

$ rsync -a --delete --stats --progress --exclude-from='./.rsync_exclude' ./ your@domain.com:~/your-rails-folder/

This will copy all files from ./ to the remote ~/your-rails-folder/

The --exclude-from flag is useful to exclude extra files your production server doesn’t need, ESPECIALLY the .bundle file

Here’s my .rsync_exclude:

// my-rails-app/.rsync_exclude
.bundle
tmp
log

Now, if you have new gems or migrations to run, ssh into your prod server:

ssh your@domain.com

 

And execute:

$ cd ~/your-rails-folder
// (if you use rvm, make sure to switch to the right rvm version)
$ rvm use ruby-2.2.2

 

Run bundle and rake

$ bundle install --without development test
$ rake db:migrate RAILS_ENV="production"

 

If you haven’t already precompiled your assets earlier in your local machine, do it now:

$ RAILS_ENV=production bundle exec rake assets:precompile

 

Finally, restart your webserver. Depending on what you’re using, this step could be different.

$ killall -USR1 dispatch.fcgi

 

Voila, forget installing Capistrano or writing complicated deployment scripts. This will get you up and running with a production server in no time.

Gist: https://gist.github.com/c177e377f044d1bb1c0fd678056224ae

[College Tips] Use less salt, eat less sodium

 

In college, you will eat lots of high sodium meals and snacks. Energy drinks, soda, potato chips, burgers, fries, pizza, chicken strips, ramen, etc are all high in sodium. Since too much sodium is bad for you, try to consume less of it when cooking in your own apartment.

Here’s a convenient and easy way to limit the amount of salt added to your home cooked meal:

You might want to buy a container of salt to begin with. Once you have your 89 cent salt can, rip out the seal. Normal people would pull open the metal chute to pour salt. However, as Berkeley engineers, we are going to do this a better way. With the chute closed, take your nails and push into the pivot of the chute, where it is connected to the can. Flip the can upside down. Salt should start flowing ever so thinly out of the can. Ta-da!

Photo for illustration:

[College Tips] Choosing EE/CS classes

For sometime now, I’ve been wanting to write about the tips and tricks I used to survive UC Berkeley and Berkeley EECS. The combination of my recent graduation and the incoming of a new class of freshmen has finally persuaded me to pick up the laptop and start typing. Let’s hope I have enough tips to make this College Tips series worthwhile. I’ll try to make everything as relavant to every CS/EECS major at Berkeley.

I will start with a most recent question I received: “How do I choose what classes to take for each of my eight semesters?”

First, ask yourself which side of EECS you are most likely to ultimately pursue in? Almost all of the EECS majors I’ve talked to had an idea before starting their first semester.  Let’s say you answer CS with confidence, as I had. Take the lower division CS requirements (CS61A/B/C and CS70) as early as possible. By your first year, you should have completed CS61A, CS61B, and CS70. Some upper division CS classes only have CS61B as prerequisite, so go ahead and take one (I recommend CS170) in parallel with CS61C your third semester. Take 2 more upper div CS courses your fourth semester. By the second summer, you would have completed all lower division courses and 3 upper div courses. The 3 upper division CS courses will give you a much more competitive edge during your recruiting for summer internships or research positions. For the last 4 semesters, slowly knock off your other lower-div College of Engineering requirements like EE20/40 or Chem 1A.

The same can be done if you had picked EE. Take EE20/40 as early as possible, and push the CS requirements as late as possible to make time for your upper div EE courses. Why spend prime time (early semesters) on requirements that don’t help you get an internship or research position when you can simply defer them?

Here’s what I did, as reference:

Fall 2011 – CS 169, EE 122 , UGBA 175
Spring 2011 – CHEM 1A, EE 40, SOCIOL 3AC
Fall 2010 – CS 188, CS 170, ENVECON 131 (Studied abroad)
Spring 2010 – CS 161, CS 186, EE 20N
Fall 2009 – CS 61C, CS 194-4, CS198
Spring 2009 – CS 61B, MATH 54, PHYSICS 7B
Fall 2008 – CS 61A, MATH 53, PHYSICS 7A

It looks light because I was able to pass out of everything else via AP and Community College courses before coming to Berkeley. You’d want to add in the your humanity and other requirements to the schedule accordingly.

A Tip to Recruiters

Here’s a pro tip to recruiters: format your emails. I automatically delete 90% of recruiter emails without reading, and in the rare occasion where I actually open your email, at least make it easy for me to read it. You have 10 seconds to pitch before I press shift-3. Also, don’t use an email address like dballin@yahoo.com. Here’s what you don’t want to do:

Email from a "technical" recruiter. Click to enlarge.

 

HTML 5 Local Storage with Expiration

Not sure why expiration isn’t built into the HTML5 specs for LocalStorage, but I put together this little snippet today.

It uses Modernizr (http://www.modernizr.com/) to check for LocalStorage support.

AZHU.storage = {
	save : function(key, jsonData, expirationMin){
		if (!Modernizr.localstorage){return false;}
		var expirationMS = expirationMin * 60 * 1000;
		var record = {value: JSON.stringify(jsonData), timestamp: new Date().getTime() + expirationMS}
		localStorage.setItem(key, JSON.stringify(record));
		return jsonData;
	},
	load : function(key){
		if (!Modernizr.localstorage){return false;}
		var record = JSON.parse(localStorage.getItem(key));
		if (!record){return false;}
		return (new Date().getTime() < record.timestamp && JSON.parse(record.value));
	}
}
Gist: https://gist.github.com/1096149

Economic independence teaches the responsibility of freedom

While driving down the 85 today after work, I was really focused on the pressure of my foot against the gas pedel. I tried to step on it as lightly as I could to be as gas efficient as possible. In fact, for the past two weeks, I’ve been stretching those gallons of liquid gold. Ever since I had to commute to work every weekday and actually pay for my gas, my driving has become a lot more careful and a lot less reckless. On a good day, I would set cruise control to 65, and stay in the middle lane. It definitely paid off; I managed to squeeze out 30 miles to a gallon on this 10 year old Camry!

Probably because I was reading an article on Linkedin Today about parenting, I couldn’t stop thinking about the significance of economic independence. It teaches children very valuable (pun intended) life lessons. I’ve managed my own savings account since the first grade, my own checking account since I was 13, and my first credit card and stocks account as soon as I turned 18. I started generating income sophomore year of high school when I created a small business with my friend. Looking back, I’m glad I had that independence, because it comes with the freedom of deciding how to spend that money. What better way to learn that not eating out for a week means I could afford to book roundtrip flight to LA? And what better way to realize that the extra $300 solid state hard drive upgrade is basically coding for a day or closing two or three deals? Where else would I get the incentive to read into complicated tax laws and investment analysis if I didn’t have my own money on the line? I also wouldn’t be worrying about how much gas I use if I weren’t paying for it, and just this last semester, I attended all my lectures because I personally paid for the outrageously expensive tuition.

Sidetracking – this is why I believe free food won’t solve world hunger, but cheap food will.

This post was originally going to be a short reminder to myself that I should let my kids manage their own finances early, so I’ll stop writing here. I’m sure (and hope) that I won’t have to convince myself again 20 years from now.

There is some truths in this

between the ages of 10 and 20,
people who are most envied are those with beauty;

between the ages of 20 and 30,
people who are most envied are those who’ve found love;

between the ages of 30 and 40,
people who are most envied are those whose children are ones they can be proud of;

between the ages of 40 and 50,
people who are most envied are those who are successful;

between the ages of 50 and 60,
people who are most envied are those whose children are successful;

between the ages of 60 and 70,
people who are most envied are those who have happily married children and beautiful grandchildren;

between the ages of 70 and 80,
people who are most envied are those who have their health;

between the ages of 80 and beyond,
people who are most envied are those who die painlessly.

Life passes us so quickly.
In what should we invest our time?

Facebook Hacker Cup Round 1A

I stayed up till 7AM today for this, because I’m going to be busy all weekend. Too bad the submissions were all invalidated and pushed back a week, though. Here are the solutions, in Ruby as usual:

After the Dance Battle: (note: I used Dijkstra’s to search paths, but in reality, you just need BFS. That’s not the slow part, though. It takes way longer to draw out the graph than to actually calculate the path. An extra VLog(V) isn’t THAT bad.)

class Graph
  def initialize
    @graph = {}
    @nodes = Array.new
    @INFINITY = 1 << 64    
  end        
  def add_edge(s,t,w=1)     
    @graph.has_key?(s) ? @graph[s][t] = w : @graph[s] = {t=>w}
    @graph.has_key?(t) ? @graph[t][s] = w : @graph[t] = {s=>w}
    @nodes << s unless @nodes.include?(s)
    @nodes << t unless @nodes.include?(t)   
  end   
  def dijkstra(s)     
    @d = {}
    @prev = {} 
    @nodes.each do |i| 
      @d[i] = @INFINITY 
      @prev[i] = -1 
    end 
    @d[s] = 0     
    q = @nodes.compact     
    while (q.size > 0)
      u = nil;
      q.each do |min|
        if (not u) or (@d[min] and @d[min] < @d[u])
          u = min
        end
      end
      if (@d[u] == @INFINITY)
        break
      end
      q = q - [u]
      @graph[u].keys.each do |v|
        alt = @d[u] + @graph[u][v]
        if (alt < @d[v])
          @d[v] = alt
          @prev[v]  = u
        end
      end
    end
  end

  def run_alg(startpoint, endpoint)
    dijkstra startpoint
    puts "#{@d[endpoint]}" if @d[endpoint] != @INFINITY
  end
end

def run_line(data)
  gr = Graph.new

  data_arr = data.split(" ")
  height = data_arr.shift.to_i
  width = data_arr.shift.to_i

  portals = {}
  board = data_arr.map{|r| r.split("")}

  startpoint = "0,#{board[0].index("S")}"
  endpoint = "#{height-1},#{board[height-1].index("E").to_s}"

  board.each_index do |i|
    board[i].each_index do |j|
      current = board[i][j]
      if current != "W"
        gr.add_edge("#{i},#{j}", "#{i-1},#{j}") if board[i-1][j] != "W" && i != 0
        gr.add_edge("#{i},#{j}", "#{i},#{j-1}") if board[i][j-1] != "W" && j != 0
        gr.add_edge("#{i},#{j}", "#{i+1},#{j}") if i != height - 1 && board[i+1][j] != "W"
        gr.add_edge("#{i},#{j}", "#{i},#{j+1}") if j != width - 1 && board[i][j+1] != "W"

        if 1 <= current.to_i && current.to_i <= 9
          if portals[current]
            portals[current].each do |p|
              gr.add_edge("#{i},#{j}", "#{p[0]},#{p[1]}")
            end
            portals[current] << [i,j]
          else
            portals[current] = [[i,j]]
          end
        end
      end
    end
  end

  gr.run_alg(startpoint, endpoint)
end

f=File.open("input.txt", "r")
total = f.readline.to_i
(0..total-1).each do |i|
  run_line(f.readline)
end
f.close

Power Overwhelming

I can’t exactly come up with elegant code for this, so I am not going even going to bother pasting my semi-bruteforce method here. But here’s the jist:

It’s a simple high school math problem – two functions, one to maximize, one as constraint:
f(x) = maximization = total damage = X * Y
g(x) = constraint => C1*X + C2*Y = C3
C1 = G as given, C2 = W as given, C3 = M as given, X = number of warriors, Y = number of shields

After some substitution and derivative, we end up with X0 = C3/(2*C1), Y <= (C3 – C1*X)/C2
So, we just solve for X0. Here’s the tricky part… Facebook wanted an integer solution to X0, the optimal number of warriors to create, but the true optimum is not an integer. Using the true optimum as a center, I bruteforced the rest of the results. It took a while because sometimes Facebook’s solution and mine differ by over 20,000.

First or Last

I didn’t bother doing it. The explanations looked way too complicated.