📜 ⬆️ ⬇️

Website without backend: user authentication in BaaS parse.com through social networks

I will deploy the world every morning, like a rubber band on a golf ball, and roll it back in the evening. If you really ask, I will show you how to do it.
R. Bradbury

UPDATE: Parse will not work by 2017.

Introduction


This article describes the Backend-as-a-Service approach to storing and processing data. The advantages and disadvantages of a representative of such an approach, the parse.com service, are described. Briefly presented user authentication service through social. uLogin networks. The main purpose is to show how these two services can interact, so that the project does not require user registration by username and password, but at the same time, the ability to authorize users to act on objects remains.
')

About BaaS and parse.com


Parse.com is one of the most popular backend-as-a-service (BaaS) providers. BaaS approach allows you to not raise your server for storing and processing application data. This is used in mobile development and in the regular web. Parse.com has its own SDK for several platforms, including server ones. But I will talk about javascript.

The ability to work with the database via javascript without raising your server opens up excellent opportunities, for example, for the Single page application (SPA), which can be hosted on Github Pages, Bitbucket and many other free ones. The first question that I had when I heard about working with the database from the client code is the delimitation of access rights, since the keys are well known. After reviewing the parse.com documentation, I found out that user authorization is used for this. Each user has his own login and password. The SDK has methods for registering a new user by login and password, and authentication using the same data. You can add email, while parse.com itself can send customized emails to verify email.

Sample code with registration
var user = new Parse.User(); user.set("username", "my name"); user.set("password", "my pass"); user.set("email", "email@example.com"); // other fields can be set just like with Parse.Object user.set("phone", "415-392-0202"); user.signUp(null, { success: function(user) { // Hooray! Let them use the app now. }, error: function(user, error) { // Show the error message somewhere and let the user try again. alert("Error: " + error.code + " " + error.message); } }); 



Access rights are differentiated by ACLs that can be assigned to created objects. For example, set the object access to public reading, but leaving the editing only to an authorized user. Additionally, you can set restrictions on methods for working with the table. For example, you can allow everyone to write to a table, but prohibit reading to everyone except a certain group (in cases of logging, for example). In addition, the administrator is provided with a master key with which you can get full access from the client application. But in the SPA this is unacceptable, since the key can not be hidden. Of course, there is an admin panel where you can edit charts, perform CRUD operations on all data.
Admin:
image

Formulation of the problem


User authentication only by login and password can now look rough. Therefore, parse.com has in its SDK the class Parse.FacebookUtils , with which you can link user accounts with social. network. But this is the only social network that can be used via the parse.com SDK in javascript. There is Twitter, but not for javascript . What to do if you really want to authenticate users through other social services. network?

Cloud code


Parse.com , fortunately, provides not only data storage, but also the ability to execute some code on their server. Fichu they called Cloud Code . The code of created functions is inaccessible for users, which means it can be used when building requests signed by a secret key. But this is not particularly useful.

I began to choose services that have ready user authorization widgets for sites, and stopped at uLogin . A few words about the choice. Once I caught the eye of Loginza, but I was not satisfied with them, because there they asked me to enter my login and password, even to log in via Twitter. Perhaps there were some others, soc. applications that requested access to writing tweets (omg, enrages). So, uLogin has a good set of social services . networks, ready-made widget, return accessToken in javascript callback-functions, and also allows you to create your own social. user authentication applications.

Since parse.com asks to register users by login and password, I came to the conclusion that this pair can be obtained using the data returned by uLogin. To do this, you need to create the file clound / main.js in your application, in which you need to define a function. Let's call it “getCredentials”.
 Parse.Cloud.define("getCredentials", function(request, response) { var token = request.params.token; var userLogin, userPassword; response.success({'username': userLogin, 'password': userPassword}); }); 


The uLogin service allows you to customize the list of fields that it will return. But among the obligatory there are:
network - user social network identifier,
profile - user profile address (link to his page on the social network, if you can get it),
uid - a unique user identifier within the social network,
identity is a globally unique user id.

identity is, as a rule, also a url, similar to profile , so I decided to glue the username (here username ) from the network and uid .
For the password, something more secret is needed, so I decided to use the hash from identity , token , secret as a password.
identity for uniqueness, token for secrecy, because Each entry in uLogin will create a new token, known only to the user and to uLogin itself, and the secret - salt, stored in the application settings.
This approach is bad because with each new entry through uLogin , there will be a new token , and therefore a new password. Therefore, you need to save each time a new user password. However, parse.com saves the session for a long time after the user has logged in, so there is no need to authenticate each time. Ready Cloud Code .

The solution is rather suspicious in quality, but in some cases it is quite efficient. For example, if you refuse to log in users by their usernames and passwords. But even in this case, the method can be improved and stop updating the user's password after receiving the token. As another option, it is to use a random string as a temporary password instead of a hash (the awareness of this came a little later).

Of course, a temporary password is issued after confirmation of the token, by receiving data from uLogin . After that, we determine whether we have a user with this login. If not, then register. We write him the data from the social. network (pseudonym, avatar) in the repository, return a couple of username and password.
Interaction with uLogin and c parse.com takes place via https, all data is accessible only to the user himself.

Client Authentication
It takes quite a bit of code to get an authenticated user at parse.com.
Connect the uLogin widget
 <script src="//ulogin.ru/js/ulogin.js"></script> <div id="uLogin" data-ulogin="display=small;fields=first_name,last_name;providers=vkontakte,odnoklassniki,mailru,facebook;hidden=other;redirect_uri=&callback=authCallback"></div> 

Add callback function code.
 var user; window.authCallback = function (token) { Parse.Cloud.run('getCredentials', {token: token}, { success: function (data) { Parse.User.logIn(data.username, data.password, { success: function () { user = Parse.User.current(); }, error: function (user, error) { //handle it } }); } }); }; 

Here is the call to the previously written server function " getCredentials " in Cloud Code.
The next time the user logs in using var user = Parse.User.current (); You can determine whether the user is authenticated or not. If so, then the uLogin widget should be hidden.

Pros and cons of a single-page application using parse.com


pros



Minuses:



Comment:

It is possible to write other clients to the same publicly available data. If the client side allows user authentication through uLogin, then there are no barriers to managing user data. The disadvantage is that the limit on the number of requests is total.

Demo project


Looking at imhonet, bookmix, livelib, I had the idea to make my own service for storing read books. The main goal of which is a list of books, without unnecessary gusts like ratings, purchases, covers. When choosing such services, you are interested in the reliability of data storage, so that it does not work out that the project closes in a year or two, and the data will be lost. Therefore, when developing my service, I decided to use external free data warehouses, that is, BaaS. This will not pay for hosting, do not worry about the problems of software updates. Statics planned to keep on Github Pages. But once the service became dependent on parse.com, then he decided to use hosting too. For the SPA I decided to use AngularJS, as I knew him and knew what I needed from him. Connoisseurs of separation of entities will notice strange dependencies between them, but with each project on AngularJS I will learn something new about it. Now I know how to do better. Rewrite only from academic purposes considered superfluous.

Some may say that the registration of users only through social. network may entail serious difficulties to restore access to the project in case of loss of access to social. network. This problem could be solved by setting uLogin so that he asked for the user's email (and verified it himself), and then restore access by email. But there is no such thing in the demo project, since the list of books read is publicly available, which means that in case of serious problems, you can simply duplicate it to another account.

Source
Demo

PS: The demo is my production, it will not be turned off.

Upd : there was no habraeffect, there is still a lot of limit (click to enlarge)
image

Source: https://habr.com/ru/post/248511/


All Articles