Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing authentication tokens in a RESTful API without using HTTP sessions

Tags:

rest

I am building a RESTful API with multiple servers and I want to know if it's okay to store the access token in a central database server and then, for every request, verify if this access token is valid by querying the database and then performing the action given.

If I use sessions for this job, will it become non RESTful? Like even if I store the session data in a database? It's been a confusing idea to me for so long.

like image 940
MYNE Avatar asked Feb 10 '16 06:02

MYNE


People also ask

Where should authentication tokens be stored?

If any of the third-party scripts you include in your page is compromised, it can access all your users' tokens. To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server.

Do I need session in REST API?

Each REST API call by a client is associated with a web service session. A session is created when client calls Login API and stays active until it times out or is logged out. When the session is created, a session ID that looks like a GUID is generated and assigned to it by the server.


1 Answers

REST is stateless

REST stands for Representational State Transfer and this architecture was defined by Roy Thomas Fielding in the chapter 5 of his dissertation.

Fielding defined a set of constraints for the REST architecture. One of these constraints is the stateless communication between client and server, defined as following (the highlights are not present in his dissertation):

5.1.3 Stateless

[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]

So, if you keep the session state on the server, you break the stateless constraint. Hence, it's not REST. In REST you won't have a session on the server and, consequently, you won't have session identifiers.

Each request must contain all data to be processed

Each request from client to server must contain all of the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server.

When accessing protected resources that require authentication, for example, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.

Have a look at this quote from the RFC 7235 regarding considerations for new authentication schemes:

5.1.2. Considerations for New Authentication Schemes

There are certain aspects of the HTTP Authentication Framework that put constraints on how new authentication schemes can work:

  • HTTP authentication is presumed to be stateless: all of the information necessary to authenticate a request MUST be provided in the request, rather than be dependent on the server remembering prior requests. [...]

And authentication data (credentials) should belong to the standard HTTP Authorization header. From the RFC 7235:

4.2. Authorization

The Authorization header field allows a user agent to authenticate itself with an origin server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested.

Authorization = credentials

[...]

Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.

Token based authentication

When performing a token based authentication, the tokens are your credentials. In this approach, your hard credentials (username and password) are exchanged for a token that is sent in each request. Again, the authentication must be performed for every request, so you won't take advantage of any stored context on the server.

It's perfectly valid storing your tokens somewhere in your server. And it won't break the stateless constraint of the REST architecture.

Tokens

Basically, the tokens can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token):

  • Random String: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.

  • JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To find some great resources to work with JWT, have a look at http://jwt.io.

There are many databases where you can persist your tokens. Depending on your requirements, you can explore different solutions such as relational databases, key-value stores or document stores.

like image 140
cassiomolin Avatar answered Sep 21 '22 00:09

cassiomolin