Hacking and Hustling: Full User Auth Without Writing Code

Weasle your way through coding by exploiting freemium software.

The midlife crisis is a striking phenomenon common and equally inescapable to all of us. I’m fairly certain I’ve come to a turning point in my life where I too must admit I will never be cool again. I know this because I check Product Hunt on a daily basis, and I thoroughly enjoy it.

I’d estimate about 80% of things featured on Product Hunt are hilariously worthless parodies of Silicon Valley itself, real predators live for the hunt. They hunt on. At least that’s what Eric Thomas told me during a podcast on my way to the gym one morning. On this fine day, my friends, the Lion has risen.

We’re in a unique period in human history where the Middle Class simply no longer exists. This is great if you’re not an enterprise software giant because that means all SaaS pricing models have two modes: free, or ten billion jillion gazillion dollars. Sometimes when we persist, those free services might align to let us do something crazy. Handling user signups, authentication, sessions, and so forth for zero work and zero dollars is indeed crazy.

We’re going to leverage four products at once to achieve this amazing feat of laziness. While each of them may be mediocre in their own right, the whole is surely greater than the sum of its parts.

Apisentris: Generate a REST API for any DB Instantly

You get an endpoint! And YOU get an endpoint!

This is a product we've briefly touched on in the past: the gist is that granting Apisentris to your database will generate a full-on API which can modify any record of any table in any way you can imagine. Yes, that includes users.

Byepass: User Logins Without Passwords

Good luck trying to white-label this for under 20k.

Byepass is a relatively new product- if you haven’t Googled them yet, you’re in for a treat of search results. Let this be a lesson in SEO.

The premise of this service is to phase out and destroy plaintext passwords. Considering the standard of modern-day 2FA, it’s not too hard of a sell… the only thing that truly sucks about the product is their branded confirmation emails (and the dreaded“contact us for pricing” estimate when considering a white label option).

Besides saving the trouble of passwords, there is a key upside to Byepass specifically for us: since passwords are no longer needed in user sign-ups, there’s no need to pass the form along to a backend, where a framework is expecting to encrypt the blah blah blah. Give it a rest, this is my Slacking day.

Getform.io: The Cleanest Drop-in Form Solution

Capturing forms without doing the form work.

Getform.io started off with a strong goal in mind: to allow idiots who host Wordpress sites collect user information via forms… while most likely having zero clue as to how to code or even use a CMS. When submitted, form results are sent to an endpoint on the Getform side. From there, Getform already tips you off on what you should do next: they name drop Zapier, and they’re ready to party.

Zapier: You Already Know the Deal

I've simulated my entire personality in a collection of zaps.

We all know the deal with Zapier by now: it’s the glue in any Slacker’s arsenal. I can already hear the neckbeards wailing in agony at the sheer mention of Zapier. I get it, you’re insisting that Zapier is a collection of API endpoints cleverly pointed towards one another for convenience, and you could totally build that stuff yourself.

To set the record straight, you’re not going to code anything Zapier automates on its own. If you spent that much time on menial tasks, you’d be a developer valued at minimum wage. You’re not building shit- you’re playing Rocket league when you get home from work like the rest of us.

Step 1: Create a Signup Form

This part of the process is pretty easy considering all you need to do is copy and paste Getform's boilerplate from the first page you see when you log in:

<form action="https://getform.io/f/54775468-578-45765718d-567-5474657567564" method="POST">
    <input type="text" name="name">
    <input type="email" name="email">
    <input type="tel" name="tel">
    <button type="submit">Send</button>

Step 2: Get Zapped

Now it’s game time. I just as easily could have named this post “dope shit you can do with Zapier without paying the Ludacris 50-dollar per month free to incorporate pipelines.” I still haven’t ruled it out, really. Here’s what’s waiting for you:

chain chain chaaaaiiinnnn…

As you might imagine, we're getting some pretty basic input from this signup form: in my case, simply username and password. Before we go saving two values to a weak af database table somewhere, let's add a little spice to the equation in the JavaScript step.

Give the People What They Want

What do people want? pictures of their own dumb faces, mostly! Luckily, there's a service called Gravatar which might just be able to provide us with just that. Sometimes when you sign up for a service, you might notice they already have your mugshot on file. At some point, you signed up for a service that associates your email address with a profile picture, simply by applying an md5 hash to your email.

We're going to do the same for our users.

Set up your input data:

So far so good!

Great, now all that's left is encrypting that email address in vanilla Javascript thanks to Zapiers inability to handle imports:

var MD5 = function(d){var result = M(V(Y(X(d),8*d.length)));return result.toLowerCase()};function M(d){for(var _,m="0123456789ABCDEF",f="",r=0;r<d.length;r++)_=d.charCodeAt(r),f+=m.charAt(_>>>4&15)+m.charAt(15&_);return f}function X(d){for(var _=Array(d.length>>2),m=0;m<_.length;m++)_[m]=0;for(m=0;m<8*d.length;m+=8)_[m>>5]|=(255&d.charCodeAt(m/8))<<m%32;return _}function V(d){for(var _="",m=0;m<32*d.length;m+=8)_+=String.fromCharCode(d[m>>5]>>>m%32&255);return _}function Y(d,_){d[_>>5]|=128<<_%32,d[14+(_+64>>>9<<4)]=_;for(var m=1732584193,f=-271733879,r=-1732584194,i=271733878,n=0;n<d.length;n+=16){var h=m,t=f,g=r,e=i;f=md5_ii(f=md5_ii(f=md5_ii(f=md5_ii(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_ff(f=md5_ff(f=md5_ff(f=md5_ff(f,r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+0],7,-680876936),f,r,d[n+1],12,-389564586),m,f,d[n+2],17,606105819),i,m,d[n+3],22,-1044525330),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+4],7,-176418897),f,r,d[n+5],12,1200080426),m,f,d[n+6],17,-1473231341),i,m,d[n+7],22,-45705983),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+8],7,1770035416),f,r,d[n+9],12,-1958414417),m,f,d[n+10],17,-42063),i,m,d[n+11],22,-1990404162),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+12],7,1804603682),f,r,d[n+13],12,-40341101),m,f,d[n+14],17,-1502002290),i,m,d[n+15],22,1236535329),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+1],5,-165796510),f,r,d[n+6],9,-1069501632),m,f,d[n+11],14,643717713),i,m,d[n+0],20,-373897302),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+5],5,-701558691),f,r,d[n+10],9,38016083),m,f,d[n+15],14,-660478335),i,m,d[n+4],20,-405537848),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+9],5,568446438),f,r,d[n+14],9,-1019803690),m,f,d[n+3],14,-187363961),i,m,d[n+8],20,1163531501),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+13],5,-1444681467),f,r,d[n+2],9,-51403784),m,f,d[n+7],14,1735328473),i,m,d[n+12],20,-1926607734),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+5],4,-378558),f,r,d[n+8],11,-2022574463),m,f,d[n+11],16,1839030562),i,m,d[n+14],23,-35309556),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+1],4,-1530992060),f,r,d[n+4],11,1272893353),m,f,d[n+7],16,-155497632),i,m,d[n+10],23,-1094730640),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+13],4,681279174),f,r,d[n+0],11,-358537222),m,f,d[n+3],16,-722521979),i,m,d[n+6],23,76029189),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+9],4,-640364487),f,r,d[n+12],11,-421815835),m,f,d[n+15],16,530742520),i,m,d[n+2],23,-995338651),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+0],6,-198630844),f,r,d[n+7],10,1126891415),m,f,d[n+14],15,-1416354905),i,m,d[n+5],21,-57434055),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+12],6,1700485571),f,r,d[n+3],10,-1894986606),m,f,d[n+10],15,-1051523),i,m,d[n+1],21,-2054922799),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+8],6,1873313359),f,r,d[n+15],10,-30611744),m,f,d[n+6],15,-1560198380),i,m,d[n+13],21,1309151649),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+4],6,-145523070),f,r,d[n+11],10,-1120210379),m,f,d[n+2],15,718787259),i,m,d[n+9],21,-343485551),m=safe_add(m,h),f=safe_add(f,t),r=safe_add(r,g),i=safe_add(i,e)}return Array(m,f,r,i)}function md5_cmn(d,_,m,f,r,i){return safe_add(bit_rol(safe_add(safe_add(_,d),safe_add(f,i)),r),m)}function md5_ff(d,_,m,f,r,i,n){return md5_cmn(_&m|~_&f,d,_,r,i,n)}function md5_gg(d,_,m,f,r,i,n){return md5_cmn(_&f|m&~f,d,_,r,i,n)}function md5_hh(d,_,m,f,r,i,n){return md5_cmn(_^m^f,d,_,r,i,n)}function md5_ii(d,_,m,f,r,i,n){return md5_cmn(m^(_|~f),d,_,r,i,n)}function safe_add(d,_){var m=(65535&d)+(65535&_);return(d>>16)+(_>>16)+(m>>16)<<16|65535&m}function bit_rol(d,_){return d<<_|d>>>32-_}

var value = inputData.email;

var grav = MD5(value);

output = {username: inputData.username, email: inputData.email, gravatar: grav};

Oh yes, friend. It's like that.

Step 3: Create Records in Our Database via the API

Could we enter records into MySQL via a direct connection? Sure, if you like wasting time creating SSL certs for your lame boring DB connections. That’s 5 minutes that could be spent playing Rocket League.

Instead, consider the following alternative of passing a JSON object to a relational database and having it turn out just fine. It feels like we’re prancing through a field of freemium software Unicorns- just like in my dreams:

Have fun with your .pem files, losers.

Step 4: Let There be Confirmation Emails

All that's left is welcoming our users to our family with a handwritten, generic templated email courtesy of Byepass.

Don’t worry about these publicly visible email addresses btw: they’re all bots.

In case you're ignoring the documentation completely (understandable), our last request is a POST request to https://byepass.co/redirect. In fact, here- just take the docs:

Endpoint: https://byepass.co/redirect

Method: GET or POST

Headers: {"Content-Type: application/x-www-form-urlencoded"}

Request Variables:

  • identifier (email address)
  • block_proxy (BOOL 0 for to no restriction, 1 to block verifications from known proxies) (Paid accounts only)
  • key (Byepass app key)

We've Finally Made It

We may never be the spring chickens we once were, but we all experience chills of envy when we watch those reality TV shows featuring Midwestern people with mental illnesses hoard coupons and score the sickest grocery store heists ever to air television legally. That's who we are now: we're the crazy, deal-seeking, thrill-chasing coupon ladies of Silicon Valley.

All I know is it feels great to not work myself further out of the debt I accrued while attempting to offset the crippling, burnt-out depression bestowed upon us by the technology industry. For this moment, life is fine. Finally.

Todd Birchard's' avatar
New York City Website
Product manager turned engineer with an ongoing identity crisis. Breaks everything before learning best practices. Completely normal and emotionally stable.