So I want to made user login via facebook

I assume I can’t use user.create\user.login api because I won’t ask user to provide password, I want to use facebook userId and access token only

Basic flow:

  1. In mobile app I’ll use facebook plugin to login.

  2. After user logged in on device I push access_token and FB user Id to my custom API

  3. From server side I can now check if this access_token is valid and match user id (via graph.facebook.com/…)

  4. After validation I will check if username “facebook_{userid}” exists in mysql, create it if not exist

  5. Use mysql to store additional user data

So should I manually create new records for coronium database, cc_users table? Because with it I can view users statistic in webmin. But downside is that I should fill password (and probably some other columns) with trash data - because I’m not using them, but they are required.

Another way is to create new table for my users in coronium db. Then I’ll have full control on it, but lose webmin visualization. And I wonder: can future updates affect tables created in coronium database?

Thanks for reading this wall of text :slight_smile:
Any thoughts?
 

Hi,

Thats a false assumption.

I get id from user external service and use it to automatically create a user account, using the user module in coronium core.

You can also make your own user table, with the obvious limitations you’ve mentioned, the choice is yours.

You are clearly interested in coronium core so I suggest you dive in and test drive it to find out what can be done and not

These days you even have a free trial period  :slight_smile:

Theory will only get you so far and I suspect people on the forum are more inclined to help with actual code problems than theoretical cases like this one where you can find the answer yourself by firing up coronium core and try it out.

CC is a great product, you wont be disappointed.

I already have coronium server installed, I just experimenting with modules for now.

I get id from user external service and use it to automatically create a user account, using the user module in coronium core.

So my actual code problem is that password is required. Do you set up some default password to create user from user module?

Edit : I also figured out that  core.users object is available on api side. But the problem is that this method is asynchronous: it require listener. And api method should return response in synchronous way: I don’t have possibility to “wait” until listener fired

Hi,

Yeah I generate the user password on user creation together with a user hash id which is stored with user data.

I know there is no wait functionailty in lua but how come you cant wait for the reply before “moving on” ? Everything in corona in regards to network calls are async so this is one you need to code according to.

It is possible to create you own “wait” logic using booleans but i find it more hassle than calling functions from async callbacks.

I mean I can’t wait on server side (in coronium api)

So code I want:

function api.upsertUser(params) --validate params code --check if user exist if (userNotExist) then core.users.create({username = params.username, password="some default password"}, myListener) else core.users.login({...}, myListener) end --I should return value from api function, return from listener will not work return {} end

yeah you can

check if user exist and wait for callback on callback evaluate result and either create user or login

you can also do a 2-in-1 call like this

login user (our own core api call) on server, if user dont exist, create, else login return reply to client

the latter is slightly more efficient but it wont matter if you do 2-3 api calls during user creation or just 1.

also, if you are using digitalocean, there is no practical api call limit to your droplet.

hope that makes sense. not writing code here just describing logic.

Yeah, thanks

But I think I’ll make custom logic on api side to avoid multiple calls from client.

then async calls wont be an issue for you 

Hi,

What columns do you need for Facebook login (its been a while since i’ve used it)? Perhaps having support for Facebook login in the users system would be a good idea,

There is a server-side users module, but it requires a different approach, and if not handled properly could mess up the users system, so I never documented it for safety. That may be a good way to add custom users though. I could add documentation if you’re interested in trying that approach. You would then need to write your own custom server-side login logic.

The “coronium” database is not safe from updates, as new features or adjustments might be made in the future, so its best not to change it.

-dev

For now I trying to build flexible OAuth system (at least for Facebook and Google).

I use Facebook user Id for now

function api.createOrUpdateUser(params) if (params == nil) then return core.error("provide parameters!") end if (type(params.loginSystem) ~= "string" or not checkLoginSystem(params.loginSystem)) then return core.error("loginSystem missed or unknown") end if (params.userId == nil) then return core.error("User id is required") end local userId = core.mysql.escape(params.userId) local lSystem = core.mysql.escape(params.loginSystem) local record, err = core.mysql.selectOne(DB\_NAME, { tbl = USERS\_TABLE, where = "externalId = " .. userId .. " and loginSystem = " .. lSystem, columns = { "id" } }) if (err) then return toGeneralError(err) end local isUserExist = record ~= nil print("user exist?",isUserExist) if (not isUserExist) then core.mysql.insert(DB\_NAME, { tbl = USERS\_TABLE, values = { username = userId, loginSystem = lSystem, data = core.json.encode({ counter = 1 }) } }) end ...

Hi,

Just so I understand a bit better.

So, you would be creating a new user, with username and email for instance (no password), and then associate the client_id from the external provider to that user.

On login, you want to use the client_id from the external provider to access/login the user.

Does that sound about right?

-dev

I don’t need even username and email. For facebook I pass Id and token, which I could validate on server side (see https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken )

Username and email can be optional fields to use

Hi,

For sake of discussion, do you need to actually use the manual login flow if you’re using the Facebook plugin?

I’ve been reading through this document https://developers.facebook.com/docs/facebook-login/multiple-providers

-dev

Hi, actually it’s not full login flow on server

I use Facebook plugin, so user just click “login using facebook” button. Then I just store some data, which associated with facebook account (so when user will login on another device he will get his data back).

Validating token on api side just guarantied that request from client coming from authorized user

Hi,

Do you get any type of permanent Facebook client ID, or is it only the access token?

If you get a permanent id, then we can associate that with a Coronium user record, so you would know that the client is valid.

I could then add another method of logging in the user using email and Facebook ID which you should be able to get back from the FB login.

If your app’s own custom login system uses an email address to uniquely identify each account, you should also ask for the person’s email address (using the email permission) during the Facebook Login flow. Read our guide to requesting permissions to find out how to do this.

Your thoughts?

-dev

Do you get any type of permanent Facebook client ID, or is it only the access token?

I registered an app on https://developers.facebook.com.
Then I used Facebook plugin to login on androide and get userId.
Then I use facebook.getAccessToken() and pass token+id to api
Then on api side I validate id+token pair (to be as secure as possible)
 

local urlFormat = "https://graph.facebook.com/debug\_token?input\_token=%s&access\_token=%s|%s" local url = string.format(urlFormat, params.token, FACEBOOK\_APP\_ID, FACEBOOK\_APP\_SECRET) local resp, err = core.network.getJson(url)

It works for now
 

I could then add another method of logging in the user using email and Facebook ID 

Yes, I can request email permission.

But guide you linked says that if user registered on facebook using phone number email could be empty.
 

Hi,

Ah, did not catch that about phone number.

Ok, well as long as there is some type of immutable id from Facebook, then I think I can make this work. I’ll be exposing a couple new user module methods on the server-side.

I’ll be using the following fields in an “Oauth” table to associate to the Coronium user:

  • user_id (for relationship)

  • client_id (from FB or Google)

  • access_token (for whatever)

  • provider (FB or Google)

Are there any other fields that you think you would need?

I’ll start working on it now. And then I’ll send you preview build link for server download to test.

-dev

So this would be on the server-side and I can use it in my api? I still don’t want to write multiple client side calls for one operation.

Hi,

Yes, it will be on the server-side. Basically it provides another way to generate a user record, as well as, a “login” that will allow you to still have the Webmin stats.

-dev

Ok, so I’m interested in this (however my custom approach is almost finished)