I am developing Django + React project and I'm caught with this security approach concerning login and managing views for the logged in user.
I am using django-rest-framework or DRF for my RESTful API. And I'm using django-rest-knox for authenticating user logins since I am implementing Token-based authentication (instead of session-based which uses CSRF).
Question: Is it a good idea to save user's id and token in local storage?
Currently, I have a /auth/login/ API endpoint that handles the backend logic of logging in user and returns JSON response of login details upon successful login (including user id and token).
In my frontend, I use redux and redux-persist so the user's login details are kept even when the site is refreshed. The way redux-persist do it is that it saves the response in local storage. This means that the user id and token can be accessed and changed anytime thru dev tools.
If user will then make a POST request to an API that requires a Token authentication header, the frontend will look into that local storage for the token value to be supplied to the request header.
If user will then make a POST request to an API where the user id is required in the request data, the frontend will also look for the id in the local storage.
Localstorage is not safe, especially for storing tokens and ids. Any user can go to the browser's developer tools, see and also edit its contents, for example.
You could check on Django's sessions, so you can store data securely at server side and keep its contents associated with a specific user. There is a great tutorial at Mozilla that explains sessions in a clearer way than the official documentation.
I'm setting up a Django-React application, with authentication through third party CAS. The process of CAS authentication looks like following:
The web application redirects the user's browser to CAS's login URL with a "service" parameter, for instance https://cas.com/login?service=http://myapp.com.
Once the user has been authenticated by CAS, CAS redirects the authenticated user back to the application, and it will append a parameter named "ticket" to the redirected URL. Its ticket value is the one-time identification of a "service ticket". For instance, http://myapp.com/?ticket=abcdefg.
The application can then connect to the CAS "serviceValidate" endpoint to validate the one-time service ticket. For instance, https://cas.com/serviceValidate?service=http://myapp.com&ticket=abcdefg.
In response, CAS shall return an XML containing the authenticated user id, for instance,
<cas:serviceResponse>
<cas:authenticationSuccess>
<cas:user>johnd</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
I've done some research and found it could be implemented in mainly two ways:
Serve react as part of Django's static content.
Standalone react single page application(SPA) through JWT.
I've tried the first approach and it works, but the problem is that every time I want to test the authentication with React, I need to build the static file first and put them in Django, which is kind of slow. So I would like to try the second approach.
My question is that is there any best practice I could implement for the standalone approach? If I were to implement JWT, is it safe to store the access token in localStorage or cookie?
Many Thanks!
I'm using Django REST framework JWT library for authentication in my django application. And I thought the whole idea of using JSON Web Token Authentication was NOT having a database trip in every request.
But it still retrieves user's data (which is stored in the token's PAYLOAD) from database per request.
What am I doing wrong?
The webtoken mechanism and the server authentication internals are rather orthogonal.
The web token just allows the holder to say who they are. It is similar to holding a user's username and password, except the token can be revoked without the user having to learn a new password. This authentication technique has nothing to do with whether the server will do a database access.
If you wish to eliminate a DB access during authentication on the server, you can use some sort of authentication caching mechanism like django-cached_authentication_middleware.
In my App I need to communicate with my Django website. Some resources require authentication so I need user login.
But this does not happen in a browser or a web view. I need to use Object-C to issue a login request and handle the response - basically to store the session ID I guess.
On the web server side, how should I do this in Django? To have a stand-alone view for that and return JSON maybe? How can I get the newly generated session ID though?
I wouldn't get the session ID. I believe logging in a user is more geared toward a web interface. I would create an API that serves the resources you need in your app. http://en.wikipedia.org/wiki/Representational_state_transfer Authentication would probably be best suited for a private/public key pair or some other similar popular api authentication system.
You don't need to make any changes to your authentication system, save for maybe making sure the login form is usable on the smaller screen. Cookies work the same on iOS as they do on the web. You can display a modal UIWebView with your login form. After the user logs in, presumably you are setting a session cookie. If you make a subsequent request to the domain the cookie matches, the cookie should be sent along. You want to look into the HTTP 'Accept' header field, which specifies the content type the client expects to receive. In your controller (view?), you'll want to check the 'Accept' header, and return the appropriate content type, probably 'application/json' (or a custom type for your API).
I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.