Top

post

Oath 2.0 and OpenID Connect

OAuth 2.0 and OpenID Connect For Dummies

Many of us struggle with this subject. What’s up with that? And what are those, anyway?

Intro

Authentication 101

(The amazing doodles in this post are made by my dear friend Kim)

This is what implementing authentication used to be like. Photo by Jeremy Bezanger on Unsplash

We Have Protocols for This

OAuth

The Terminology

The Authorization Code Flow

Scope

Back Channel and Front Channel

GET https://accounts.google.com/o/oauth/v2/auth?client_id=stav123&redirect_uri=https://stav.com/callback&scope=profile&response_type=code&state=foobar
POST www.googleapis.com/oauth2/v4/token
Content-Type: application/x-www-form-urlencodedcode=oGd5GkJs5mKrtgH5&
client_id=stav123
client_secret=stav_secret_123&
grant_type=authorization_code
{
  "access_token": "FgrgGsd456GdSghDsgsa3fHg",
  "expires_in: 4560,
  "token_type": "Bearer"
}
GET api.google.com/whatever
Authorization: Bearer FgrgGsd456GdSghDsgsa3fHg

Other Possible Flows

OAuth For Authentication?

OpenID Connect

OpenID Connect Authorization Code Flow

JWT

This example is taken from https://connect2id.com/learn/openid-connect which is a great source of learning.
Taken from https://jwt.io/introduction — also a great source of learning!

Let’s Take a Short Break

Refresh Token

End of Short Break

Memes are taken from http://www.memeking.co.il/

Summary

 

Also posted in Medium

cat on a laptop

The First World Problem of Working From Home

So this post is going to be a rather more personal one.

Like most of the rest of the hi-tech world around the globe these days, I’ve been working from home for the past three weeks. Before I talk about what I’m experiencing, let me just say that I’m ever grateful for my home and everyone that’s in it and that the most important thing is that we’re all healthy. Also, we both still have our jobs, which isn’t trivial either. And with that note, please let me have my little rant, okay?

I think I’ve been switching rapidly between the different stages of the Kubler-Ross model since the whole thing started. I was grieving my old life, which was flawless. Everything was perfect just a minute ago: the perfect family, the perfect job, and the perfect balance between the two.

Then the coronavirus changed the rules of the game, forcing us all to stay locked together, except mandatory activities such as buying groceries. Now our days look like this: one of us works for an hour or two while the other one is parenting the kid (which is just about the most intense age), then switch. And repeat. Switch. And repeat. Until she goes to sleep and we both collapse dead on the couch, not even having the energy to properly panic about the pandemic and our futures because we’re too busy acting normal.

 

work with kids

Photo by  Charles Deluvio

 

We live in a small urban apartment, and the minimalistic work area is a part of the shared area. So the work intervals aren’t at all isolated from the rest of the activities happening around. As a result, the already short interval in which I need to concentrate and write some code also includes a lot of me entertaining the kid simultaneously (every now and then she’d insist on it) or having to split my attention or worse, just abandon what I was just doing altogether and attend to some different random matter. Of course, this whole “method” doesn’t work great unless your purpose is to lose your mind, and indeed I’ve been barely keeping it together, but let me break it to what I think are the biggest problems in it:

Context Switching

What I just described makes it nearly humanly impossible to deliver anything on time and bug-free. Even back in the normal office days, I would find it extremely costly of mental resources to switch to a new task before having a full closure on the previous one. The same goes for multiple meetings scheduled throughout the day. The farther distance your mind drifts from a task, the longer it takes you to get back on track, and moreover, the more cognitive resources you have to use in order to do so. Now imagine having to switch like that ten times a (good) day.

More contexts equal more work. Except it’s less work done.

How Can You Tell Your Private Time From Work Time?

I can’t really.

And I think that’s the most urgent issue. I mean, it sure was clear enough when I was either at the office or at home. Now, however, as I am working on this very post draft on my quiet weekend, some calendar event invitation literally just came from the team director. And why wouldn’t it? We’re all at home anyway, might as well not ignore the rest of our tasks waiting and the meeting invitations sent. What would it matter if the guy waited until the end of the weekend to send it?

But it matters. It matters because the exhausting endless attempt of multitasking from home makes your 50% to 100% employment a 300%. These days I won’t decline a meeting scheduled at 16:30 even though that would normally be out of my scope. But what IS my scope now? I really don’t know anymore. If you judge by the weird times I pushed code lately or by the weekends lost to work, you’ll probably find the entire concept of boundaries is gone out the window now, and that I live in a total nightmare of constant diffusion of the two worlds.

So Here’s what I’m going to start trying, and I suggest you do as well:

Cut Yourself Some Slack

Turn Slack notifications off sometimes. Yes, I had to get the slack pun out of the system but really it’s not about that. Be kind to yourself. Because when this is all over, you’d still want to come out of the other side a person. Set boundaries. Decide on your work hours. Be it at standard office times or at night time if you’re that type, but don’t make yourself available 24/7. Your family is more important, and above all, you are. Respect your own time.

Of course when I say “you” I really mean “I”. I’ve not been functioning ideally lately and it has a lot to do with me just learning the boundaries thing for the first time. Never had to before.

 

slack off

Photo by  Pankaj Patel

Communicate Your Struggles

They’re everyone’s now.

You might feel like all your friends and coworkers are crushing it at work right now, finishing online courses, taking up piano lessons and keeping fit. That’s probably not true.

Don’t just stay there alone with your fear of disappointing everyone and your strive for impossible perfection in the weirdest of times. Communicate. Even set a video meeting just to talk about it with the team. And don’t just talk. Leave with action items. Such as predefined work schedules and times of availability. Summarize it on a shared document. Create a method that is applicable to times of chaos and works for your team. The important thing is that everything is on the table. But there’s a big added value: you’re not alone anymore. You’ll find that a lot of people are struggling with the same things, and guess what? You just helped them.

Well, at least I hope I did.

 

(This was also posted in Medium)

GraphQL is awesome

GraphQL – The REST is History?

GraphQL Is Really Buzzing Right Now.

What’s that all about?

GraphQL, created by Facebook in 2012, first stormed into our lives in 2015 when it was open-sourced by them. It is said to revolutionize the way we think about APIs. Before we dive into what that big statement means exactly, I need to say: GraphQL was made to solve a rather specific set of problems, or if you will, the shortcomings of the REST approach. In order to understand if it’s the right approach for us, we need to understand what those shortcomings are.

RESTful Routing Is Fine

REST APIs have become pretty much the standard over the years, and for good reasons, too. RESTful routing makes it really easy to communicate with someone else’s API without any special effects or third-party libraries, providing a way of mapping between HTTP verbs (get, post, put, delete) and controller CRUD actions (create, read, update, delete).

In simpler words, it’s just a set of conventions used to fetch or manipulate data from the server. When we talk about RESTful routing, we really talk about HTTP requests; what types of requests we need to create, read, edit or delete a record. This set of conventions tells us what the API looks like so that we know what resource to expect from the server when we go to a certain URL.

REST APIs inform the client about the result of their request using status codes, and additional information in the body of the request.

So far so good.

But REST Has Its Flaws.

And I’m going to elaborate a bit about some of the major ones.

Multiple Requests

Typically, we would need to access several server-defined endpoints, and we might need to do multiple round trips to get everything we need. For example, in an app that has users and blog posts, to get a specific post made by a specific user we would send a GET request to URL /users/{userid}/posts/{postid}. Now if we want to know something else about the user at the same time, like their birthdate or workplace, we have to make another request to /users/{userid} to get the user entity.

That’s two requests. Can we get it for one?

Server Driven Representation

Say we have a Linkedin type social network. The data consists of users, and for each user, we have their info, their connections (other users), workplaces and positions.

Cute database

When we design the data store here, we need to remember that each company is also an entity we want to access, and it has its basic info and a list of users who work there. The positions should also be entities of their own so that we can pull a user out from the collection of positions, same as with the companies. The user can have a key that points to a certain company and position that they’re associated with.

Entities

Take a couple of minutes to think about how our REST API here is going to look if we want to be able to fetch the following:

  1. The list of users (/users) — ok, seems legit!
  2. A specific user (/users/{id}) — still good.
  3. A specific user’s list of connections (/users/{id}/connections) — sure.
  4. A list of the companies associated with all of a user’s connections — Oh. Wait.

The last one here is kinda tricky.

Kinda heavily nested relationship

As far as RESTful conventions go, we can create a request for each user’s connection’s company: users/45/connections/1/company/users/45/connections/2/company, etc. It’s obviously unrealistic to have that many HTTP requests.

Another option is to customize an endpoint like this: /users/45/connections/companies. So, in theory, we’ll get all the companies related to the specified user’s connections. However, if we‘re going to create tons of very customized endpoints like that, we’re going to have to actually make this thing work on the backend, and put together the queries to fetch those very particular pieces of data — so that’s hardly scalable in real life.

Or we can go about making even more customized single endpoints like users/45/connections-companies, and design those fixed data structures so we can return them.

That’s where the RESTful conventions really get thrown into the trash, which also brings us to the next issue:

Overfetching / Underfetching Data

For each company, we’re probably going to have to return the entire model — including name, id, location, year founded, and then again, an entire list of users associated with it… What if we actually just wanted to get a list of names? On the other hand, if we are using endpoints that return fixed data structures, they could be lacking other pieces of data and forcing the user to make additional requests.

This use case involves heavily nested relationships between pieces of data, and it seems that the RESTful conventions won’t make much sense here, because if we don’t want to make a ridiculous number of requests to the server, we would either be customizing many weird logic endpoints or be extremely overfetching data.

GraphQL to the Rescue

These are the challenges around RESTful routing and data serving that GraphQL is here to solve. The rest of this reading is going to be a brief showcase of what it can do.

Everything is Connected

GraphQL doesn’t deal with dedicated resources, but instead, treats the data as a graph.

Graph

With the GraphQL query language, we can query exactly what we need and describe exactly what attributes we want to get back in the response.

Here we can query something like this:

In this example, we’re telling GraphQL to find the starting point user with the given ID, then go find all the users that are user 15’s connections, and then the company in each of these users, and have it return just its name. GraphQL will walk through all the records associated with the given starting point, all the way to the final result.

And we can get as specific as we want with a single query, like fetch all the CTOs among a certain user’s connections, or the companies’ locations for all the connections of a connection, or what have you. As long as the schema supports it — we can go wild. GraphQL helps us reduce network requests by allowing us to do so much in a single query, and no more overfetching or underfetching data, since we only fetch exactly what we need.

Error Handling

A GraphQL query can have many resolve functions, for whatever types you want to query in it. While in REST we’d get a response status code to know what the error is, GraphQL will not fail the entire query, but instead will always get a status code of 200 and send the error message along with the response to the client. If we’re querying this:

For a user that is currently unemployed, we’d get back this:

And see we still get other data, like the first and last name. Only the company is null. How cool is that?

To Wrap It Up

There’s much more to GraphQL than this very brief introduction, and a lot more to REST too. GraphQL has a whole different approach regarding API design, and it solves many of the challenges we had to deal with using REST. It also has its own challenges (and that can be a new post).

Is one of these approaches better than the other? Like everything in technology, the answer to that is very rarely a confident yes. Each of them has its advantages and weaknesses, considered against your client needs of the API. However, in the world of social networks, as shown in the examples above, in my opinion, GraphQL is a winner.

Hope this was helpful!

(This was also posted on Medium)

code-mess

Caught in a Bad Abstraction

Abstractions are tricky. When used properly, they can help you maintain your code over time. However, a wrong abstraction can add a lot of unnecessary complexity to the project and trap you in an even worse maintenance hell.

So how to avoid the wrong abstraction? How to recognize when an existing abstraction isn’t right for us anymore? And what can we do about it at this point?

But first, what exactly is an abstraction?

I find formal dictionary definitions for this to be too… well, abstract. But this is a great definition: the process of taking away or removing characteristics from something in order to reduce it to a set of essential characteristics.

I like this definition best because it is applicable to both code and real life.

Abstractions allow us to think of big and complicated concepts as small simple things. If you were to draw a bathroom door sign, you’d probably draw a circle to symbol a person’s head, and some straight lines for the body, and probably add some triangle skirt for the lady symbol because it’s 1950. But the point is, while humans are a lot more complicated and detailed than a few lines and shapes, you won’t need to worry about stuff that happens in deeper layers of abstraction. Your drawing generalizes a person just fine while hiding away their inner biological and psychological mechanisms.

 

abstractions make it easy to communicate.

 

Abstractions, therefore, make it possible for us to communicate.

In the world of code, it’s essentially the same. Often we use built-in classes and prototype functions to be able to operate a complicated thing in a simple manner. We’re handed just the class “intention”, and not the actual implementation of it. Abstraction is one of the core concepts in computer science, and more specifically, one of the four key concepts of object-oriented programming.

There are few approaches for abstracting your code:

DRY

Don’t Repeat Yourself

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

(The Pragmatic Programmer)

Well, obviously, you’d say. And you wouldn’t be wrong. Code duplications are ugly and hard to maintain. Imagine fixing the very same bug in four or five different places. Ew. So this principle simply suggests that if you recognize a couple of components or more having some duplicated logic, go ahead and extract that logic so that the different parts of the application can share it.

WET

I’m actually not sure who coined that one. WET is here to describe a code that is not, well, DRY. But Wikipedia has some suggestions regarding what this acronym stands for: “write everything twice”, “we enjoy typing” or “waste everyone’s time”.

Let’s go with the first one. It’s the least passive-aggressive. And here is a really good description, by Conlin Durbin:

You can ask yourself: “Haven’t I written this before?” two times, but never three.

As Durbin suggests, this shifts the focus towards your own judgment and is taking into account that different use cases may require different handling. It allows you to consider a little duplication. By the third time you stumble upon the same repeated piece of logic, stop and abstract it away.

The Wrong Abstraction

Duplication is far cheaper than the wrong abstraction.

 

(I highly recommend clicking on the above quote and reading the entire article by Sandi Metz. It is really great.)

This is a very well-phrased principle. The wrong abstraction can and will become far more complex and harder to read or maintain than a code duplication, over time.

Everybody’s intentions are good, of course. You’re all just trying to write good code. At some point, you might recognize an unnecessary duplication; some components which share some functionality. You go ahead and do the right thing: extract the functionality and have them all lean and clean.

Then a new requirement shows up. They always do. One of the components now has to have a teeny tiny change in its behavior, but still pretty much follows the standard. With one or two small modifications that will be added to the abstraction, everything is still good. Right?

Right?

 

Oh no.

 

This is how it goes down:

Say you have a very simple dialog component that can receive a title, a text, and a button.

Very lean. Capable of receiving some data and present it.

Sometime later, a few new requirements come. You need to handle types. As the dialog may be of type warning/success/danger etc, you’d probably want to change its class accordingly so that the relevant style guide can kick in. No problem, we’ll add a “type” prop.

Also, you are asked to handle the case in which there is no title and the case in which there is no body text.

This will add us a few conditions, but well, what can you do.

Some more time passes. Then comes another new requirement: we also need to handle a whole bunch of buttons, instead of just one. So we’ll now pass an array of buttons with their entire data and map through it. Still not a big thing to ask of this component, I mean, right? It should support such a trivial case.

What if you also wanted to support an input? You could then use this dialog for a lot of other things, like login / create account for example. And what about an array of inputs? It could be a long form or a wizard of sorts.

I’m all for it. But let me just say that inputs will also need validations. Let’s say we pass the validations as another prop.

Our dialog is becoming more and more complex.

Just one last thing (for now): why don’t we also support a table format? Heck, let’s do it. Data might identify itself as a table. We’re not here to judge.

Yes, the table rendering better happen in its own component, but you get the point.

Blargh! This is pure hell. We wanted a lean container of data but we really had no control over what data is coming, and in what shape. Therefore we ended up with tons of conditional paths. But the worst part is that: the component doesn’t know its purpose anymore. What’s a dialog really? Isn’t everything a dialog?

You can see where this is going. As time passes, the abstraction is not really abstract anymore, but a huge bunch of different permutations depending on parameters and cases. After a few more iterations, the code is no longer readable. A year or two from now, the new employee in your team will not be able to understand what this abstraction actually does. Neither will you.

Then, things will break.

True story.

 

Back to duplication

The Dialog abstraction became useless. The somewhat shared logic wasn’t reason enough to force this one component to handle all data and cases at once. If we destructure it into duplications, we will easily see what is actually needed in all its possible permutations, and what isn’t. Then we can try and think of a new abstraction.

There is more than one way to approach this problem. At this point, your best shot is to re-duplicate, so you can see where you actually stand.

 

Where are you going with this?

I would like to suggest some helpful takeaways.

  1. If you find yourself in a situation like this, take a step back. Break the abstraction back into duplications. Now observe once again: which are the unique parameters of each component? Leave them there, and delete any logic that isn’t particularly needed in this component. Now you can write a new abstraction, based only on simple shared logic, with no conditionals and side effects.
  2. If you find yourself adding conditional scenarios and passing parameters to an abstraction — you probably got the abstraction wrong. For an abstraction to work fantastically in a large number of contexts, it has to identify its precise use case.
    (on a side note: that can’t always be the case. The more complexity the abstraction is trying to hide, the bigger the chances of it to leak, which doesn’t necessarily mean it’s bad or useless. But we’re talking about simpler cases here).
  3. Same goes if have to think more than a minute about how to name your abstraction. A good abstraction has to declare exactly what it does. If you don’t know how to name it, maybe you’re not sure what it does. That’s never a good sign.
    (Pro tip: try to avoid names like “util” or “manager”)
  4. Write code that solves your current problems. Don’t attempt to get away with a perfect silver bullet abstract code that will be written once and prevent all your future problems. If that were ever the case, none of us would have to work at all by now. The more common scenario is that your abstract joker will at some future point be used as a five-ton hammer on every problem. While we all try to lay good foundations, it’s really more like gardening than, say, building a house. Most of the decisions are reversible, and some will be revisited.
  5.  

Coding is much like gardening.

 

Therefore don’t be afraid of challenging even old abstractions that have been there for ages. It appears that the more complicated and confusing the code is, the more we tend to keep going with it, thinking it must have been the only way. 

I highly recommend not to fall into this trap. Assume every piece of code made perfect sense when first written, but it might not still be the case. Allow yourself to question these things and you’d be surprised.

 

(This was also posted in Medium)