HTTP PUT:
PUT puts a file or resource at a specific URI, and exactly at that URI. If there's already a file or resource at that URI, PUT replaces that file or resource. If there is no file or resource there, PUT creates one. PUT is idempotent, but paradoxically PUT responses are not cacheable.
HTTP 1.1 RFC location for PUT
HTTP POST:
POST sends data to a specific URI and expects the resource at that URI to handle the request. The web server at this point can determine what to do with the data in the context of the specified resource. The POST method is not idempotent, however POST responses are cacheable so long as the server sets the appropriate Cache-Control and Expires headers.
The official HTTP RFC specifies POST to be:
- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation.
HTTP 1.1 RFC location for POST
Difference between POST and PUT:
The RFC itself explains the core difference:
The fundamental difference between the
POST and PUT requests is reflected in
the different meaning of the
Request-URI. The URI in a POST request
identifies the resource that will
handle the enclosed entity. That
resource might be a data-accepting
process, a gateway to some other
protocol, or a separate entity that
accepts annotations. In contrast, the
URI in a PUT request identifies the
entity enclosed with the request --
the user agent knows what URI is
intended and the server MUST NOT
attempt to apply the request to some
other resource. If the server desires
that the request be applied to a
different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make
its own decision regarding whether or not to redirect the request.
Additionally, and a bit more concisely, RFC 7231 Section 4.3.4 PUT states (emphasis added),
4.3.4. PUT
The PUT method requests that the state of the target resource be
created
or replaced
with the state defined by the representation
enclosed in the request message payload.
Using the right method, unrelated aside:
One benefit of REST ROA vs SOAP is that when using HTTP REST ROA, it encourages the proper usage of the HTTP verbs/methods. So for example you would only use PUT when you want to create a resource at that exact location. And you would never use GET to create or modify a resource.
Overall:
Both PUT and POST can be used for creating.
You have to ask, "what are you performing the action upon?", to distinguish what you should be using. Let's assume you're designing an API for asking questions. If you want to use POST, then you would do that to a list of questions. If you want to use PUT, then you would do that to a particular question.
Great, both can be used, so which one should I use in my RESTful design:
You do not need to support both PUT and POST.
Which you use is up to you. But just remember to use the right one depending on what object you are referencing in the request.
Some considerations:
- Do you name the URL objects you create explicitly, or let the server decide? If you name them then use PUT. If you let the server decide then use POST.
- PUT is defined to assume idempotency, so if you PUT an object twice, it should have no additional effect. This is a nice property, so I would use PUT when possible. Just make sure that the PUT-idempotency actually is implemented correctly in the server.
- You can update or create a resource with PUT with the same object URL
- With POST you can have 2 requests coming in at the same time making modifications to a URL, and they may update different parts of the object.
An example:
I wrote the following as part of another answer on SO regarding this:
POST:
Used to modify and update a resource
POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/
Note that the following is an error:
POST /questions/<new_question> HTTP/1.1
Host: www.example.com/
If the URL is not yet created, you
should not be using POST to create it
while specifying the name. This should
result in a 'resource not found' error
because <new_question>
does not exist
yet. You should PUT the <new_question>
resource on the server first.
You could though do something like
this to create a resources using POST:
POST /questions HTTP/1.1
Host: www.example.com/
Note that in this case the resource
name is not specified, the new objects
URL path would be returned to you.
PUT:
Used to create a resource, or
overwrite it. While you specify the
resources new URL.
For a new resource:
PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/
To overwrite an existing resource:
PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/
Additionally, and a bit more concisely, RFC 7231 Section 4.3.4 PUT states (emphasis added),
4.3.4. PUT
The PUT method requests that the state of the target resource be
created
or replaced
with the state defined by the representation
enclosed in the request message payload.
Best Answer
Simple Basic Auth with vanilla JavaScript (ES6)
note: This "middleware" can be used in any handler. Just remove
next()
and reverse the logic. See the 1-statement example below, or the edit history of this answer.Why?
req.headers.authorization
contains the value "Basic <base64 string>
", but it can also be empty and we don't want it to fail, hence the weird combo of|| ''
atob()
andbtoa()
, hence theBuffer
ES6 -> ES5
const
is justvar
.. sort of(x, y) => {...}
is justfunction(x, y) {...}
const [login, password] = ...split()
is just twovar
assignments in onesource of inspiration (uses packages)
The above is a super simple example that was intended to be super short and quickly deployable to your playground server. But as was pointed out in the comments, passwords can also contain colon characters
:
. To correctly extract it from the b64auth, you can use this.Basic auth in one statement
...on the other hand, if you only ever use one or very few logins, this is the bare minimum you need: (you don't even need to parse the credentials at all)
PS: do you need to have both "secure" and "public" paths? Consider using
express.router
instead.