How to login a Django account from an iOS App? - django

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).

Related

Is saving user's id and login token in local storage a good idea?

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.

How to implement SSO (single-sign-on) with third party CAS (Central Authentication Service) for a Django-React application?

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!

Understanding the Client's Responsibilities in OAuth 2.0

I've been trying to learn the inner workings of OAuth 2.0 in my own RESTful app, and I can't seem to find any good explanation of how my Javascript client handles the process.
At this point, I have the client (an Angular 2 SPA) ask the user for their username and password (running Django Rest Framework along with Django Oauth Toolkit). The client makes an AJAX post to the server (specifically to /o/token), and using the resource owner password credentials flow is authenticated and receives the response with the token.
Now, assuming I'm doing everything correctly up to this point, I'm unsure how to properly handle the token from that point forward.
At this point, I'm having my Angular app save the token in a variable and attach the authorization header (with the token) to the calls made to the API. This works as far as granting the correct permissions, but im having a hard time understanding how to maintain persistence of the header (so if the user navigates to a different page, the token is still callable). Initially I stored it in a cookie, but I have concerns with security.
So, first, am I understanding all this correctly? What kind of security concerns should I take into account here? And, of course, how can I save the token on the client?
Yes, you need to store access tokens as user session data because they should be persistent. For example if user leaves your site and then reopens he expects to see himself logged in.
It will be better if you make your sessions server-side: user-agent will store only session ID and all user data will be in your database. User don't need his access token, only your application does.
Instructions for implementation of server-side sessions for Django look pretty simple:
If you want to use a database-backed session, you need to add 'django.contrib.sessions' to your INSTALLED_APPS setting.
Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.

Authentication with Flask/Django and a javascript front end

I'm struggling to understand how flask_login or django knows when a user logs in that they retain access?
If I were to use ReactJs or Angular with flask-restful or django/tastypie, what is being added to the header/body of future json requests to ensure that my user stays logged in?
This is done via sessions, which is based on cookies. From the Flask documentation:
In addition to the request object there is also a second object called session which allows you to store information specific to a user from one request to the next. This is implemented on top of cookies for you and signs the cookies cryptographically.
and the Django docs:
Django provides full support for anonymous sessions. The session framework lets you store and retrieve arbitrary data on a per-site-visitor basis. It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID – not the data itself (unless you’re using the cookie based backend).
So, the requests to the server automatically include a cookie that indicates some ID that the server then uses to figure out what the session data should be for the given user. In general, when Ajax requests are made from client-side applications to the server, this cookie is included and so ensures that the user is considered to be logged in for those requests.
In some cases, you can also (optionally) manually add a special header to HTTP requests to indicate which user is logged in.
See also Securing RESTapi in flask for some more information.
If you use REST service then you should take a look at oAuth. In other words it uses token which you attach to every request from client to server and the last can determine which user sent this request by this token.
On the other hand, you can use cookie or session to determine a user status. And in this case you don't need to add any headers to your request.
Also I recommend you this package for Django - Django Rest Framework (there you can read more about token and auth via REST) and this extension for Flask.

Django-allauth, JWT, Oauth

I have an AngularJS Single Page Application that uses a Django backend API based on the Django Rest Framework. The API is protected via django-rest-framework-jwt. I would like to use django-allauth for account management and authentication on the server side.
I am just missing one single piece in the flow: How does my Oauth-Token from the client get transferred into a JWT-token? Basically, I would like to do as described here http://blog.wizer.fr/2013/11/angularjs-facebook-with-a-django-rest-api/ based on python-social-auth.
So my question is, how do I implement the ObtainAuthToken class from the link with django-allauth?
There are usually two login flows with social login: client-side ("Javascript SDK") and server-side. If your server needs to be authorised, it's usually a lot easier to go through the server-side flow. And that's also what all-auth does I think (and you didn't mention you use a frontend library like the blogpost you mentioned does).
Now the challenge is to provide the token from the server to the frontend. You would probably load the token in the HTML of the initialisation of the SPA, and then from Angular save the token client side (cookie, localStorage, etc.) so the session isn't lost on a refresh.
If you don't want the user to leave your app, you can open your /accounts/login/ or /accounts/signup/ url in a new window. In that new window they authorise your app, and your server receives the token upon return. There, you will have to generate a JWT token manually, and render that into the template so that javascript can access it. With js in that popup window, you can then communicate with your app that opened the popup and pass it the token – see this SO answer for an example – so it can save it.
Django-allauth provides signals that let you hook into the social login process. In your case, I would recommend subscribing to the allauth.socialaccount.signals.pre_social_login signal. The code will look something like this:
from allauth.socialaccount.signals import pre_social_login
#receiver(pre_social_login)
def create_jwt_token(sender, request, sociallogin, **kwargs):
# dig into the sociallogin object to find the new access token.
We used hello.js for O-Auth at the company I worked at.
You provide a shim on the Python end and get the refresh token and whatever other data needed once the user connects their social account.
We redirect them via Django to the page they attempted to access from their OAuth provider's page.
Each user still has their own email account which is needed for the JWT, but you could assume that whatever email is in the scope of their social account is their email then use django's functionality to create new users: User.objects.create(email=emailStringFromOauthData) etc.