85

I need to authenticate a client when he sends a request to an API. The client has an API-token and I was thinking about using the standard Authorization header for sending the token to the server.

Normally this header is used for Basic and Digest authentication. But I don't know if I'm allowed to customize the value of this header and use a custom authentication scheme, e.g:

Authorization: Token 1af538baa9045a84c0e889f672baf83ff24

Would you recommend this or not? Or is there a better approach for sending the token?

Henke
  • 4,445
  • 3
  • 31
  • 44
Thomas Watson
  • 6,507
  • 5
  • 33
  • 43

5 Answers5

54

You can create your own custom auth schemas that use the Authorization: header - for example, this is how OAuth works.

As a general rule, if servers or proxies don't understand the values of standard headers, they will leave them alone and ignore them. It is creating your own header keys that can often produce unexpected results - many proxies will strip headers with names they don't recognise.

Having said that, it is possibly a better idea to use cookies to transmit the token, rather than the Authorization: header, for the simple reason that cookies were explicitly designed to carry custom values, whereas the specification for HTTP's built in auth methods does not really say either way - if you want to see exactly what it does say, have a look here.

The other point about this is that many HTTP client libraries have built-in support for Digest and Basic auth but may make life more difficult when trying to set a raw value in the header field, whereas they will all provide easy support for cookies and will allow more or less any value within them.

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • 10
    Nice to hear that is how OAuth works. I not sure using cookies makes the client implementation simpler. Unless your client is a browser, then the rules for working with cookies (path, expiration etc.) are more complicated to implement in a client than just remembering to set a header field. Most client libraries makes it fairly simple to set the correct headers. – Thomas Watson Dec 11 '11 at 19:33
  • 2
    @ThomasWatson while I can't disagree with you over the cookie scope points, it shouldn't really matter here. The scope of HTTP authentication (using the `Authorization:` header) is per domain. This means that if you set the domain of the cookie to "this domain" and the path to "/" it will have an identical scope to that of HTTP auth. However, it is really up to you - but as Julian Reschke points out, you probably shouldn't define a new authentication scheme unless you `feel that you have something of generic use` - something that could be used in another application. – DaveRandom Dec 12 '11 at 10:05
8

In the case of CROSS ORIGIN request read this:

I faced this situation and at first I chose to use the Authorization Header and later removed it after facing the following issue.

Authorization Header is considered a custom header. So if a cross-domain request is made with the Autorization Header set, the browser first sends a preflight request. A preflight request is an HTTP request by the OPTIONS method, this request strips all the parameters from the request. Your server needs to respond with Access-Control-Allow-Headers Header having the value of your custom header (Authorization header).

So for each request the client (browser) sends, an additional HTTP request(OPTIONS) was being sent by the browser. This deteriorated the performance of my API. You should check if adding this degrades your performance. As a workaround I am sending tokens in http parameters, which I know is not the best way of doing it but I couldn't compromise with the performance.

Abhishek Kumar
  • 674
  • 1
  • 6
  • 15
  • I'm also considering just sending my sessionID in http params. Why do you say this is not the best way? It seems it has the advantage of robustness against firewalls stripping headers, and also against cross origin performance degradation. What are its disadvantages? – thund Aug 01 '16 at 18:32
  • 1
    The disadvantage is only in the case of GET request. I had to authenticate user using my `Authorization token` (sensitive data) for my application. For the same reason we shouldn't send sensitive data in GET, we shouldn't use authorization token in params. As per w3 https://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3 "HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data". – Abhishek Kumar Aug 03 '16 at 08:02
  • You can store the token in cookies if you don't like headers. (Don't confuse the token with session id). Note that by PUT and DELETE it will send the OPTIONS anyways... Be aware that most of the time you use a server side REST client and a browser is not considered to be a very good REST client. – inf3rno Sep 15 '17 at 11:05
5

This is a bit dated but there may be others looking for answers to the same question. You should think about what protection spaces make sense for your APIs. For example, you may want to identify and authenticate client application access to your APIs to restrict their use to known, registered client applications. In this case, you can use the Basic authentication scheme with the client identifier as the user-id and client shared secret as the password. You don't need proprietary authentication schemes just clearly identify the one(s) to be used by clients for each protection space. I prefer only one for each protection space but the HTTP standards allow both multiple authentication schemes on each WWW-Authenticate header response and multiple WWW-Authenticate headers in each response; this will be confusing for API clients which options to use. Be consistent and clear then your APIs will be used.

2

I would recommend not to use HTTP authentication with custom scheme names. If you feel that you have something of generic use, you can define a new scheme, though. See http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p7-auth-latest.html#rfc.section.2.3 for details.

Julian Reschke
  • 40,156
  • 8
  • 95
  • 98
  • The document to link to is a draft of HTTP/1.1. I've been trying to look in the final standard and can't find anything about that I have to register custom schemes. Could this not just be, that during the drafting process, they wanted to find and agree on the default schemes? – Thomas Watson Dec 11 '11 at 19:39
  • Thomas, the document I referenced is the revision of RFCs 2616/7 (which did not have a registry for schemes). It's work-in-progress but is getting close to completion. – Julian Reschke Dec 11 '11 at 20:19
1

Kindly try below on postman :-

In header section example work for me..

Authorization : JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwiZ2V0dGVycyI6e30sIndhc1BvcHVsYXRlZCI6ZmFsc2UsImFjdGl2ZVBhdGhzIjp7InBhdGhzIjp7InBhc3N3b3JkIjoiaW5pdCIsImVtYWlsIjoiaW5pdCIsIl9fdiI6ImluaXQiLCJfaWQiOiJpbml0In0sInN0YXRlcyI6eyJpZ25vcmUiOnt9LCJkZWZhdWx0Ijp7fSwiaW5pdCI6eyJfX3YiOnRydWUsInBhc3N3b3JkIjp0cnVlLCJlbWFpbCI6dHJ1ZSwiX2lkIjp0cnVlfSwibW9kaWZ5Ijp7fSwicmVxdWlyZSI6e319LCJzdGF0ZU5hbWVzIjpbInJlcXVpcmUiLCJtb2RpZnkiLCJpbml0IiwiZGVmYXVsdCIsImlnbm9yZSJdfSwiZW1pdHRlciI6eyJkb21haW4iOm51bGwsIl9ldmVudHMiOnt9LCJfZXZlbnRzQ291bnQiOjAsIl9tYXhMaXN0ZW5lcnMiOjB9fSwiaXNOZXciOmZhbHNlLCJfZG9jIjp7Il9fdiI6MCwicGFzc3dvcmQiOiIkMmEkMTAkdTAybWNnWHFjWVQvdE41MlkzZ2l3dVROd3ZMWW9ZTlFXejlUcThyaDIwR09IMlhHY3haZWUiLCJlbWFpbCI6Im1hZGFuLmRhbGUxQGdtYWlsLmNvbSIsIl9pZCI6IjU5MjEzYzYyYWM2ODZlMGMyNzI2MjgzMiJ9LCJfcHJlcyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbbnVsbCxudWxsLG51bGxdLCIkX19vcmlnaW5hbF92YWxpZGF0ZSI6W251bGxdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltudWxsXX0sIl9wb3N0cyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbXSwiJF9fb3JpZ2luYWxfdmFsaWRhdGUiOltdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltdfSwiaWF0IjoxNDk1MzUwNzA5LCJleHAiOjE0OTUzNjA3ODl9.BkyB0LjKB4FIsCtnM5FcpcBLvKed_j7rCCxZddwiYnU

Madan Dale
  • 43
  • 3
  • 1
    Are you really sending password/hash in JWT? It is a simple base64. – Zakhar May 21 '17 at 11:43
  • 1
    @Zakhar: it is pretty typical practice for SPAs is to encapsulate entire user session within JWT (since it's a complete json document), removing need for session storage on server side. – cowbert Aug 10 '17 at 05:01
  • @cowbert: I'm not sure if it's typical to encapsulate something more than some kind of a session token in JWT (see for example [this post](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/)). – Alexander Abakumov Aug 30 '17 at 20:04
  • 1
    @AlexanderAbakumov that article full of misleadings, he got some points, but a lot of his points does not make sense and some of then he just against without any reason, I can tell he just loves cookies and I think he needs to get some from Bakery and fix his article, I got a lot of situations that I used cookies and wastes days of work, JWT with localStorage saved me a lot of headache and time, it is just 2 hours of work and bang, never visit it again. I wonder if he ever developed a mobile app, tried browsers with tightly restricted security rules and so on. – Al-Mothafar Apr 30 '19 at 08:52
  • @Al-Mothafar: I'd appreciate if you expand on your statements like `that article full of misleadings`, `a lot of his points does not make sense`, etc. in some way (meaning, it's probably something beyond a comment here). Maybe you could write an answer or a blog post? It'd be really interesting to compare arguments. – Alexander Abakumov Apr 30 '19 at 14:18