How do I get flat texture projection on a object without distortion?
Use the Texture Coordinates of your Camera

Add a texture coordinate node and choose the camera output. If all coordinates had the same depth values, then the texture won't be distorted. You can simply reduce the length of the coordinates so that their z value equals 1 by dividing the coordinate by their z value.
Use a Vector Math node for the division and you have scale and ratio invariant view coordinates.

You will notice, that the texture still changes when altering its scale. This is because the Z coordinate is 1 and it's beeing scaled. If you don't want that, then multiply the Z coordinate with 0 with a vector math multiplication node (set X and Y to 1 though, because we don't want to change them).


The setups above will still zoom in and zoom out. They don't change when the camera is moved, but change when the cameras focal length decrease or increases.
However, since we have the relation of the camera coordinates and the window coordinates we can counteract this by multiplying the coordinates with the quotion of a single dimension of window / camera.
The following node setup will produce axis-equal window coordinates independently of camera position, rotation, or focal length.

It works perfectly in cycles, but causes some artifacts in EEVEE in the center due to zero division.