Nathan Wailes - Blog - GitHub - LinkedIn - Patreon - Reddit - Stack Overflow - Twitter - YouTube
Website (Web) Development
Table of contents
- 1.1 Child pages
- 1.2 Related pages
- 2 Interesting Info
- 3 All-in-one Courses
- 4 Analytics
- 5 Auth
- 6 General
- 7 Career advice
- 7.1 Courses
- 8 CDNs
- 8.1 CloudFlare
- 9 HTTP
- 9.1 Books
- 10 HTTP/2
- 11 MVC
- 12 Payments
- 12.1 No coding required
- 12.2 Coding required
- 13 OAuth
- 13.1 Usage advice
- 13.2 Resources
- 13.3 Fakebook Login
- 14 REST (Representational state transfer)
- 15 Security
- 15.1 Dealing with bots
- 15.2 SSL / HTTPS
- 16 Sessions
- 17 WebP
Child pages
- A/B Testing
- Ajax (Web Development)
- Bootstrap.js
- Performance / Speed / Optimization / Monitoring (Web development)
- Reputation systems
- SPAs / Single-Page Applications
- Static websites / assets (web development)
- Tools (Web Development)
- UI / UX / Design (Web apps)
- URL Structure (Web Development)
- Cloud hosting / VPSes / Digital Ocean / PaaS / Dokku
Related pages
Web languages:
Interesting Info
Quora: What consumer Internet companies had a large number of users but failed to monetize?
Quora - How do modern websites check user passwords without storing the clear-text password in the database?
All-in-one Courses
Udemy - The Complete Web Developer in 2018: Zero to Mastery
As of 2018.01.08, it's rated 4.9 with 230 reviews.
Tech taught:
HTML5, CSS, Bootstrap 4, Javascript, React, Git + GitHub, Node.js, Express.js, NPM, PostgresSQL, SQL
Analytics
used by Pieter Levels, apparently.
Auth
Summary of the chain-of-thought that leads to the best-practice way of doing auth
Let’s first imagine a situation where a user doesn’t “log in” in the sense of storing any record of themselves in the browser but just submits their username and password with each request that requires authentication. So, like, a user arrives at the landing page and wants to view their personal inventory page, so they put in their username and password in some form on the homepage and hit ‘View Inventory’, and the server receives that username and password and sends back a server-side-rendered view of that page.
But what if the user wants to do a bunch of things related to their account? It’s obviously annoying to need a username/password form on every page that might send a request to the server that requires authentication, and it’s annoying for the user to have to type their username and password in for every request. So what we’ll do is, when the user submits the username and password the first time, we’ll save it to localStorage, and then for any future requests we’ll just pull the username and password from localstorage and send them to the server.
The problem with this is that it’s like keeping your bank account number and routing number written on a piece of paper on your table at Starbucks. Hackers are sometimes able to use malicious JavaScript to grab that username and password from localStorage. For example, suppose you have an ‘add a comment’ feature, and a hacker includes JavaScript in that comment and sends it to your server, and your web app unknowingly includes that injected code as it’s sent to various users viewing your site. To avoid this kind of attack, we can store the username and password in an HttpOnly cookie instead, as JavaScript is not allowed to see/read/access that kind of cookie. So the way it’ll work is: we’ll send the username and password to the server just once to log in, then the server sends us back the username and password as HttpOnly cookies that are automatically sent with future requests to the server.
But this is still not as safe as it could be. It’s like keeping your bank account number and routing number written on a piece of paper on your dining room table in your home: less dangerous than Starbucks, but if someone breaks into your home they’ll be able to grab it. In our case, if a person’s PC or phone gets infiltrated by malware, the hackers can read the value of the cookies. To guard against this, we shouldn’t store the username and password as a cookie, but instead just store something like a *temporary* password that the server gives us after we send it the username and password. Because it’s temporary, if a hacker steals it, there will be a smaller window for them to take advantage of the stolen password.
This temporary password is normally set up to work in one of two ways:
the first way is called using “sessions”: we can store a random string we’ll call a “session token” (temporary password) both on the user’s browser and the server, and have the server check the database every time to see if it’s still “active”. That way if someone manages to steal or access the token, we can set up the web app to allow the user to log into the site from another computer and click a button telling the server to disable the other session (session token). For example, imagine if you log into your email on a shared computer at a hostel and then forget to sign out: with this method you can disable that session. We can also limit the permisson associated with this token, so it’s not allowed to do certain admin-related things like changing the password. So if the token’s stolen and used immediately, the thief can cause chaos in the account (for example, sending emails from the owner’s account) but they can’t take total control of the account and lock out the real owner.
The problem with this first approach to a temporary password is that the database needs to be queried every time the user wants to do something, to look up the session token and see what user it’s associated with.
A second approach to temporary passwords is using JWTs: we create a JSON token that includes the user ID, token expiration datetime, permissions, etc. and sign it using a secret that only the server knows. The user then sends that with each request, and the server can verify that it created the token and then see what the user ID is without querying the database.
The problem with the second way is that you can’t immediately revoke the JWT: once you give it, it’s valid for the duration it says it is. So, for example, if it includes what the user has permission to do, and you want to immediately block a user from doing/seeing something, they’ll be able to continue taking that action as long as that token is valid.
As a way to get past the downsides of the above two common methods, Redis suggests instead using the first method (sessions) but pinging Redis instead of the database directly.
A further issue from the format of the token is whether to have one token or two: an access token and a refresh token.
Reasons to have two:
Save db calls. One reason to have two is that you can get the benefits of a JWT without as much of a security issue: you could include the user’s ID and the expiration of the token in the (access) token itself, thus saving the backend from needing to query the database for that information for each request.
Extra security. Because the access token is short-lived (say, an hour), if the access token gets stolen (for example, if someone hacks into the server receiving the access token), they won’t have a long-lived token.
However this is only helpful if you have two servers: one server issuing the tokens (the identity server) and the other potentially-less-secure server only receiving the access token (the resource server). For most smaller web apps there will be just one server handling both auth and the resource API.
However it seems that if you use Redis to avoiding touching the db, and you only have one server acting as both the identity server and the resource server, there may be no significant advantage to having both an access token and a refresh token instead of a single long-lived session token.
How long should refresh tokens last for?
Summary: one of the architects(?) of the access token / refresh token (OAuth?) standard gave an example of the exploit they're trying to mitigate and basically they were envisioning a situation in which you have a separate identity server and resource server (so, like, Google is providing the identity server and the resource server is your web app), and then your web app (resource server) gets hacked and the hackers have all of the access tokens: "query param in a log file on an insecure resource server, beta or poorly coded resource server app, JS SDK client on a non https site that puts the access_token in a cookie, etc".
So in a situation like that, you'd obviously want to reduce the amount of time the hackers have to use those access tokens to cause chaos. So think about how much damage a hacker could do with someone else's access token in 1 minute / 5 minutes / 1 hr / etc. and set the lifespan that way.
The guy even suggests the refresh token could be kept valid until it's revoked: "an access token good for an hour, with a refresh token good for a year or good-till-revoked"
I haven't been able to find anyone explain the kind of threat that an expiring refresh token is meant to guard against.
I can see how requiring the user to provide their password for critical actions is a good way to ensure that if the access token or refresh token are somehow stolen, the hacker still won't be able to (for example) lock the original owner out of the account by changing the password.
General
Career advice
Courses
Udemy
Running a Web Development Business: The Complete Guide - 4.6 stars, 710 ratings
CDNs
CloudFlare
Pieter Levels wants to use CloudFlare but he has a problem where Namecheap doesn't let you use its email-forwarding feature if you have your nameservers with a different company (and CloudFlare requires you switch your nameservers to them).
Search his Twitter feed for "CloudFlare" to see what he's said about it.
CloudFlare is apparently totally free for "average Joe's" because they get useful data and relationships from it, and they then make most of their money from big corporate clients. It's like the "whale" strategy in free-to-play games.
HTTP
Books
HTTP/2
Before I go into detail with all the different webservers, you can use CloudFlare to get HTTP/2 without touching your backend at all. CloudFlare have enabled support for HTTP/2 a while ago. Since CloudFlare works as a caching proxy in front of your infrastructure, it doesn’t care about your actual server technology, complexity or topology. In my opinion, this is currently the easiest way to get HTTP/2 while still reaping most of the benefits. In April 2016, CloudFlare even added support for HTTP/2 push.
HTTP/1.1 and HTTP/2: A Performance Comparison for Python
The short answer, at least for me, is that HTTP/2 is underwhelming. For effectively-serial clients like Requests doing web-scraping (or any form of work where the response body is the major component of bandwidth use), HTTP/2 is a bust. The overhead in terms of complexity and network usage is massive, and any gains in efficiency are eliminated if HTTP/1.1 is deployed in any sensible way (allowing gzip and connection reuse). For clients that are more parallel, HTTP/2 has the potential to have some advantages: it limits the number of sockets you need to create, it more efficiently uses TCP connections and it avoids the need for complex connection-pooling systems. However, it does so at the price of tremendous complexity. The computational workload is substantial compared to HTTP/1.1, and ends up providing relatively limited benefits to the client.
Who're the big winners from HTTP/2, then? Two answers: browsers and servers. For servers, they have to handle fewer concurrent connections (so tying up fewer system resources) and can more effectively distribute resources to clients (thanks to server push). For browsers, they can avoid the current limit on the number of concurrent connections per host, while taking advantage of complex flow-control and prioritisation schemes to maximise the efficiency of their bandwidth usage. This is difficult for a generic non-browser client to do in any intelligent way without pushing the burden of those decisions onto their user, and even if it worked, most non-browser clients don't have these specific problems.
https://blog.cloudflare.com/http-2-for-web-developers/
Really good info here
MVC
2013.11 - ASP.NET - Single-Page Applications: Build Modern, Responsive Web Apps with ASP.NET
This is a good explanation of Single-Page Applications (SPAs).
It also has a helpful explanation of MVC.
"The MVC pattern dates back to the 1980s and early graphical UIs. The goal of MVC is to factor the code into three separate responsibilities. MVC has many variants, and the literature on MVC is often confusing and contradictory. Perhaps that’s not surprising for a design pattern that started with Smalltalk-76 and is still being used in modern Web apps. So even though it’s good to know the theory, the main thing is to understand the particular MVC framework you’re using."
Payments
No coding required
Looks very interesting...
I found out about it from this guy: http://javebratt.com/ionic-starters/
He's selling code via gumroad...very interesting.
This is what Real Python uses. It looks really cool.
Coding required
General
PayPal
How to charge credit-card holders periodically even if they don't have a PayPal account:
PayPal - Enhanced Recurring Payments for PayPal Payments Standard
$19.99 monthly fee
No setup charge
No monthly minimum
No cancellation charge
Transaction fee: $0 to $3,000 in sales - 2.9% + $0.30
TheSiteWizard - How to Put an Order Form or Buy Now Button on Your Website Using PayPal
How to work with Instant Payment Notifications:
2009.03.04 - Using PayPal's Instant Payment Notification with PHP
This seems like a pretty good guide. It has lots of pictures.
This guide also shows what code to include to create a new user account when the person's purchase is successful.
2011.09.10 - PayPal IPN with PHP
This was a very helpful guide. It includes a link to a library (php file) which apparently makes the whole process a lot more streamlined.
Here's the library it links to: https://github.com/Quixotix/PHP-PayPal-IPN
2012.07.12 Change the IPN url on existing subscription
Very important to know: Unfortunately, there is NO WAY to change the IPN url for existing customers/subscriptions.
That means that if you have multiple products / websites on the same web host and want your IPN listener on that web host, you must share a single IPN listener between all of them.
Troubleshooting
Problem: PayPal Sandbox IPN Not Inserting Into Database - This was a problem I was having.
Stripe
How to set up "card on file" purchases:
Background
The idea here is to make it possible for your customer to make purchases with their credit card without needing to enter their credit card information. So it's basically like what PayPal does, except for people who don't have PayPal.
This is very, very useful because you then don't need to charge your customer a big amount all-at-once; you can instead charge them a bunch of smaller charges, as they continue to use the service. This lowers the initial psychological barrier that the user will feel to making a purchase, and gets the user into the habit of making purchases from you.
Examples: Amazon Kindle books, Steam games, GOG
Articles
to store card or bank account information for later use, create Customer objects or Custom accounts. In addition, Radar, our integrated solution for automatic fraud protection, only supports integrations that make use of client-side tokenization.
OAuth
Usage advice
Consider only allowing users to sign in with OAuth from sites where you can benefit from their sharing your content.
For example, Pieter Levels only allows OAuth sign-ins from Twitter and Facebook. Those two sites are also great places to have your users share information about your website. But if you allow users to sign in with Google or GitHub, then they may choose to do that instead and you won't have as easy a time getting them to help you spread the word.
Consider automatically having new users follow you on the site that they've used OAuth for.
For example, if you sign into NomadList with Twitter, Pieter has you automatically follow the NomadList Twitter account. You could do the same thing with Facebook pages.
Resources
OAuth is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords.
Twitter
Fakebook Login
How to set up a test account
How to use the JavaScript SDK
REST (Representational state transfer)
Security
https://httpsecurityreport.com
rec'd here
you can scan your website to find problems
Dealing with bots
Maybe have a frequent (like every 5 minutes or something) check using reCaptcha v3 to see if the user is looking real or automated.
SSL / HTTPS
General
Tutorials
PythonAnywhere
How to get HTTPS set up: https://help.pythonanywhere.com/pages/LetsEncrypt/
How to force HTTPS: https://help.pythonanywhere.com/pages/ForcingHTTPS
Sessions
Tutorials
2013.10.29 - MachinesAreDigging.com - How does a web session work?
Summary
Use of a session
A session is the different states of an application during the time a user is interacting with it, it is specific to the user. In other words, it's an instance of the interaction of a user with an application.
A web session is a data structure that an application uses to store temporary data that is useful only during the time a user is interacting with the application. It is also specific to the user.
Think of it as a volatile memory quickly accessible that is allocated to each user who is using the application, and when the user quits, it is destroyed.
This temporary storage could be on the file system in text files, on a database or in the internal memory of the program executing the application.
Structure of a session
The session is a key-value pair data structure.
Think of it as a hashtable where each user gets a hashkey to put their data in. This hashkey would be the “session id”.
When you say “my session” you're referring to your entry in the session object.
The session can be stored on the server, or on the client.
If it’s on the client, it will be stored by the browser, most likely in cookies.
If it is stored on the server, the session ids are created and managed by the server.
How does a server-side session work?
You, as the client, give the server your session id, and in return the server grants you access to your session data if it finds your session id stored in its session datastore.
Logged in state
Debugging server-side session problems
Why would a page reset a server-side session? Reasons for session reset?
Bad session replication
Transmission problem
Session reset in code
Session expired
Articles
2013.10.30 - MachinesAreDigging.com - Rings, bells and victory (debugging a session bug)
WebP
Detecting WebP support
https://stackoverflow.com/questions/16251004/use-webp-images-on-website
https://stackoverflow.com/questions/5573096/detecting-webp-support