I have a webapp that is built with Django. It works fine for use on the web, but now I am building a Android app. I am not sure how to go about authenticating the Android app the the Django backend, securely.
This webapp has user profiles. A user can register/login/logout using the web interface. The relevant part of urls.py looks like this:
urlpatterns += patterns('',
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', name="logout"),
)
My understanding is that after the user successfully completes accounts/login there is some cookie deposited on the browser which is used for the rest of the connections. Is this correct?
When on an Android device, given a username and password, what is the proper or best way authenticate the user to the Django backend? Do I need to get the cookie like in the browser or is there a better way?
There's a couple of ways you could do authentication, but using the existing Django session support and the cookies it uses is probably the best way.
When you connect to a Django page with the Session Middleware enabled (which you need for login) it'll set a session cookie (generally called 'sessionid', although you can customise that). The users (not) logged in state is stored server-side in a session linked by this session id (unless you're using the cookie-based sessions but's that's an item for another post).
So your Android app can just get the login page, fish out the sessionid (and csrftoken) cookies and then make a post with the username, password, sessionid and csrftoken.
That's the easy way. There's more complex options, which mostly involve making a custom view that spits back JSON and generally starts providing an API for your mobile apps as opposed to make them pretend they're browsers, but that's somewhat more complex on the Django side.
Related
I'm using couchbase lite in an android app with sync gateway and couchbase in the server and it works great.
Now I want to make a request to node.js from the android app, and i want to use the same session to authorize the user in the node.js app.
Is it possible?
Can I read the session in node and match it with couchbase?
You're asking about authorization. This is tied to authentication, but you should make sure to distinguish between the two. It sounds like what you want is to authenticate the user, then have your node piece authorize access based on this.
Having said that, it depends some on the type of authentication you're using to establish your session.
Basic Authentication (when used directly with Sync Gateway) just passes a username and password that gets checked. I think you get a session cookie after that. It would be very difficult to use that to authenticate to anything else (as in, you'd have to modify Sync Gateway code yourself).
OpenID Connect, in the auth flow, might give a few ways to possibly do this.
One simpler way is to have the node app also authenticate the user. If this flowed through the same browser, the browser will often keep state that would allow the user to bypass re-authenticating. This could be a little clunky, because you'd have to pass things off to a browser (or a webview, but there are security issues with that, too), which the user would likely notice.
Another approach would be to be to do a sort of double redirect. (I think this would work, but I haven't tried it. I can't find documentation on whether an authorization code can be used twice.) In the authorization flow, have the redirect go to the node app. Then have the node app redirect again to Sync Gateway. Both apps can ask for the ID token.
Yet another way would be to have your Android app ask for the ID token directly and pass this in some protected way to your node app. As always, you'd have to protect against replay attacks, and I'm not sure what else, so this could be challenging.
In any case, Sync Gateway is built to request the ID token itself, so any approach will need to ask for the ID token twice.
Here are some references you can look at to investigate this further yourself.
http://connect2id.com/learn/openid-connect - A nice write-up of the OpenID Connect protocol.
https://developers.google.com/identity/protocols/CrossClientAuth - Google Identity Provider documentation that addresses sharing authorization between a mobile app and a web app.
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html - A post describing the distinction between authentication and authorization, and why OpenID Connect (not OAuth) should be used when needing authentication.
Note: You can't use the Couchbase Node.js SDK on the bucket that is used by Sync Gateway otherwise it will mess up with the _sync metadata and documents won't sync properly; but you can query documents, create sessions, etc. using the Sync Gateway REST API.
You can refer to the documentation of the Sync Gateway REST API to get the list of available endpoints. And if you don't want to roll out your own HTTP wrapper, a JS library is available that runs on Node.js and in the browser: http://developer.couchbase.com/documentation/mobile/1.3/develop/guides/sync-gateway/rest-api-client/index.html.
I have a background in web development but I am very new to the mobile world. So, I'm not sure how to proceed with this situation:
The user login in the app
The credentials are sent to the server through a POST request.
If the response is ok, it redirects to the main activity.
Now, I want to know if I have to keep the user's ID or not. I know that when we are using a browser the server saves a "session" so the client doesn't need to send the ID everytime to request data. Is that also true with mobile apps (Android)?
By the way, I'm also responsible for building the REST API but don't have any experience targeting mobile devices.
Big question to answer, and it depends and not sure what server technology you are using. However I can describe an approach I implemented (.Net background).
It seems you are writing a mobile app?
The mobile app would first make an authentication call passing id and password to your login api, over https of course. Often the url would be something like
//yourwebsite/Account/Token
Your api would validate the user and if ok, issue a bearer token.
The mobile app needs to remember this token and on subsequent calls pass this in the request header. That's how the server will know who this is. You don't need to send the user id and password any more. And there may be a strong security argument for not storing the user id and password on the mobile device at all.
Now, your server code will validate the token, and you will know who and what the user can do. The token typically expires, so any mobile client needs to check for this and re-authenticate to get a fresh token.
But how will the server know this token, who it belongs to?
In an MVC world for example, there's framework code to help here. There's plenty of MVC template code. If you happen to be developing .Net api services, see this http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
If you are not .Net on the server, I'm sure there will be something else to help you along the same principals.
As for developing RESTful API's, ServiceStack is seriously worth considering. If too expensive, at least consider their approach and roll your own (especially when it comes to versioning of your api's).
You misunderstand the case with browsers, therefore your conclusion is flawed. Let me explain: When you log in to a website using a web-browser, a session is saved indeed, but not only on the server. It is saved at the client-side as well. Whenever you send a request from there on to the server, you have to send that stored information as well, called cookie to identify yourself.
Let's think about this more deeply: How would a server identify your session as being your session without getting a cookie? By IP address? Nope, the IP address can be used by many and it might change. By browser session? Yes, by browser session, which includes the cookie as well.
Now that you understand that the session is saved by both the server and the client, you surely already know that you need the very same for mobile apps as well. The client logs in, therefore a cookie is generated for the client. This should be difficult to guess. From there on, the client uses the server using the cookie created for it.
If you do not believe me, visit a website where you are not logged in, and then run console.log(document.cookie);, log in, then run console.log(document.cookie) again, then log out andd run console.log(document.cookie) again.
I have a fully functional web app, where authentication was created using Passport. The application uses client-side, cookie-based session token. Basically, when a new session happens, the client's data is stored as Base64 AND signed client-side, so that the user cannot change it.
The login/pass mechanism obviously works 100% fine. Facebook, however, doesn't. The main issue is that in a web environment, the user is expected to get redirected to the Facebook page and which is passed the redirect URL to which the token is passed etc.
In a App environment, this doesn't happen: my (basic) understanding is that the client handles the whole oauth mechanism, and it is meant to provide the server with the userID and auth token -- which must then be checked by the server using a Facebook API.
So... is there a known "path" to go from "Web based Facebook login using passport" to "App based Facebook login using passport"? Or shall I not bother with Passport at all for the app side of things?
I'm currently designing a service that will be half web app, half android app. Each user will need to be able to log in from either the android app or the web app, using an openID account. I'm hoping to target Google first for easiest integration with Android, but I'll also need some OAuth stuff later so that I can integrate with Google contacts.
The bit I'm having trouble with is how to authenticate users. The structure I've planned is that the server (probably using web.py, although that's flexible right now) serves data for the client in JSON, whether the client is the javascript browser client or the android client. However, each call needs to make sure the client is allowed access to that data.
What would be the easiest way to standardise this across the platforms?
Should I be using a session system to authenticate after logging in? Can that be made to work from an Android app? Otherwise, should I simply authenticate with google for every request?
When authenticating from the app, where should the authentication happen, through the server or straight from the app? Where should the auth token be stored in this case? (I'm assuming for a straight webapp the token should just be stored in a table in the user database?)
Sorry for the barrage of questions, but I haven't really found any resources online that clarify these issues very well.
As long as you are using HTTP, the platform doesn't matter. You can use the same form of authentication and/or sessions. The only difference would be that on Andorid you might be able to get an authentication token using the platform's AccountManager, without having to type the username and password in Google's login page.
There's a subtle difference between Authorization (OAuth) and Authentication (OpenId). Make sure you know what you are doing.
I have a rails app (rails3) that uses sessions for users to navigate upon login. I am trying to create an android app for this rails server and trying to figure out what is the best way for handling login is.
From what I've found so far, there are two possible ways:
1. Get sessions from rails server and setCookie on android side upon login
2. Use OAuth.
Which would you recommend?
At this point, I am unsure of how to manage sessions when using OAuth, that's why I am asking the question. Thanks
I encounter this problem last time as well. As we need to allow logged in user in the android to be able to query the rails server for some data. Initially we thought about sending password/username from android and then set the session and cookies in rails server, then send back the info. Android then use this cookies to determine if the user is successfully login. However, in the end we didn't do this, as the cookie information maybe hard to manage in mobile device. In the end we create a separate protection scheme for the rails server, if the android send user/password, rails server would validate, if sucessfully, we will insert a encrypted token into the database that contains user name and token. For subsequent request, the android device must send token to rails server, if the token is valid and can be found in db, the validation passed,and we will return data.
Good thing about this is it is easier to manage users. E.g. you can easily manage how many concurrent loggin you allow for the user. Or even better if needed, you can kick out some users without touching the android apps. Not quite sure if this fits your questions. Just to share.