I'm new in web development. I want to write a backend for my game and I want to authenticate it with Facebook. I'm not sure if my thinking is correct and secure enought. Of course https is a must.
User everytime app is launched sends /init request with fb user id and token.
Server check if this user id and token is valid by making request to fb api.
If everything is correct server check for user in database.
If user do not exists generate token using app secret, fb token, fb id and current date/time save it to database and send to client.
OR If user with this fb id exists send to user previously generated token stored in database.
Client is communicating with api using this token.
If this approach is correct I have few question.
Is sending user id and token everytime user launch application secure?
I want to veryfi user token and id with fb every time he use /init request due to fb access tokens not beeing alive for more than 60 days. Is this correct approach?
Now if user have his token to access my API. Every time he make a request should I veryfi it by making calls to database? Isn't this slow/expensive?
Related
I'm writing a React app that needs to have a login with Facebook button.
The React app is already communicating with a PHP API that already has a system in place for registering and logging in users with a username/password. The API generates a JWT and sends it to the front-end, which stores it in local storage and uses it to authenticate the user on subsequent API calls.
I've gotten my front-end app to the point where I'm successfully opening the FB permissions dialog, and receiving a response from FB that contains a userID & accessToken after the user grants permission.
My question is:
Do I need to store the FB accessToken if I don't need to access FB's API afterwards? Can I simply store the userID and use it for authentication?
My proposed auth flow would look something like this:
User clicks login with Facebook button, grants permissions in the dialog.
My React app sends the userID to my PHP API.
The API looks up the user in our DB by FB userID. If it finds one, it sends back a valid JWT, logging in the user.
If no user is found, the userID will be stored in the app's state, and it will begin the registration process, passing the FB userID along with the rest of the registration data when the user completes registration. The API then generates a JWT and proceeds with login like normal.
Would this be wildly insecure and a would be hackers easiest-day-ever?
Or is it safe to implement?
Trying to add facebook login to an existing login system on a project I am working on. Built with angular, using the FB JS SDK. This is primarily to allow frictionless login, and not currently that fussed about using the access tokens to make further calls with the FB API.
So as a new user, they hit the FB login, accept permissions etc, and it fires me back an access token etc. The new user is created in my DB, along with the accesstoken, FB userid, etc.
How do I now authenticate the user with the userid and accesstoken now stored in my DB? As far as I can see, the access token changes on virtually every page load / request, so next time the user hits the FB login, or I check the FB login status the only constant thing I have is the userid.
Have done various reading on SO and FB docs eg:
https://developers.facebook.com/docs/facebook-login/web
https://developers.facebook.com/docs/facebook-login/multiple-providers
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken
How should a Facebook user access token be consumed on the server-side?
... although that has only served to confuse things further.
I imagine I would take that stored accesstoken then check its validity, however due to the various instances of access tokens expiring and being invalidated, this also seems like an incomplete solution.
So my question: How do I securely authenticate my FB users with their counterpart user in my own DB?
The Facebook login request returns user id + short lived access token (client side).
Use the server side Facebook SDK to check the validity of the access token (will return user_id and app_id fields if valid).
You can trust the user_id field returned from the Facebook API to check against your existing user database.
Our app already implements oAuth to obtain the access token and secret from Intuit, and all works well.
The app takes into account that users may have multiple QBO companies. Consequently, when a user tries to authorize access to one company, our app checks whether this company has been already authorized, and if it has, the app lets the user know so and does not try to re-authorize the company.
The way we implemented this is as follows. When the authorization process starts, we send or app the list of companies (realm ID) which have been authorized. The user clicks the "Connect to QuickBooks" button and follows the wizard. Internally the app gets the request token and it is ready to make the access token request. The request token request gets us the realm ID so we can compare it with the list of already authorized companies. If the company has been authorized we do not request the access token and let the user know that the company has already been authorized.
Up until a week ago this used to work -i.e. in this case, because the app does not make a request for the access token, the access token the app has is still valid. However, now something seems to have changed so that when the app makes gets the request token, even though it does not ask for the access token, the existing access token is not valid anymore and the user need to re-authorize the company again.
Has something changed in the oAuth flow implementation ?
Thanks
OAuth tokens are valid for 180 days(bydefault). So, please check if existing tokens are getting more than 180 days old. If so, please use 'reconnect api'.
Ref - https://developer.intuit.com/v2/docs/0050_quickbooks_api/0020_authentication_and_authorization/oauth_management_api#Reconnect
One suggestion -
You can implement SSO( using 'sign in with intuit' wizard) in you app. That way you can relate end-user's SSO URL with OAuth tokens of his company while persisting those in your app's db. For the very first time, end user will generate tokens through C2QB flow. Next time onwards whenever the end user will sign in, your app should retrieve his oauth tokens using his SSO identifier(your app should show 'Disconnect' option instead of C2QB if he already has an established connection).
Thanks
My app uses Facebook Javascript SDK authorization on client side, and for authorized user app fetches access token from Facebook API, using facebook cookie with signed request and provided code, and store it into database.
Everything is working fine, but i'm wondering, when I should refresh stored access token? What if user have changes password, and have signed in/connected again.
As I understand, now she has new access token, and app should load it from Facebook. But how I can understand when I should check for a new token? Check on each request with facebook cookie doesn't work, because it's few request per second for each user (event if she didn't change a password). Or maybe i'm doing something wrong?
I mean:
I've authorized user on client side
I've cookie with signed request
Signed request is pretty enough to authorize user on server side (validate user credentials)
I can get access token by calling Facebook API, anytime when user user makes request to my app (because I need a code from signed request). So, i'm doing it when I don't have stored access token or existing access token has expired.
access token just stored in database, and can be used anytime, in different thread, maybe few minutes later (mean we don't have user request and cookie with signed request)
What if stored access token not expired, but invalidated on facebook side? I need to fetch new access token, but cookie has gone at this moment.
Currently I see only one way: store code from signed request into databse, and when we have found that we have invalid access token, try to load it. But i'm note sure that it's proper way, and not so much usable for most cases
You have client token and server token, the client one is short lived (a few hours) and the server one is long lived (60 days).
The token on the client side should not bother you too much since you can get a new one easily as it states in the "Handling Invalid and Expired Access Tokens" guide:
Desktop Web and Mobile Web apps which implement authentication with the Javascript SDK
Calling FB.getLoginStatus() or ensuring status: true is set when you
call FB.init() means that the next time a user lands on your
application and is signed into Facebook, the authResponse object you
are passed as a result of those calls will contain a fresh, valid
access token.
In this case, its simply the act of the user using your application
which implicitly generates a new access token.
The token on the server side, which you persist in the db, can not be as easily reproduced, the user has to be sent to the auth dialog again:
Desktop Web and Mobile Web apps which implement the server-side authentication flow
To obtain a fresh access token in this case you must pass the user
through the full server-side flow again: i.e. obtain a code and
exchange it for a new access token.
However, assuming the user has not de-authorized your application,
when you redirect the user into the OAuth Dialog, the user will not be
prompted to reauthorize your application, and will be immediately
redirected to your redirect_uri. This means that the re-authentication
process can appear transparent to the user.
You can of course send a client token to the server and persist that, but it's pretty pointless since it's short lived.
Another option is to use the new endpoint to extend a valid client token on the server side and then persisting that.
As for "how to know when do get a new token", on the server side when you are making api requests just check the response and see if an error returned and if so what it is (there's a list in the first url I added).
If the token has expired then just send the user to the auth dialog again (you can return some kind of code to the client side and do it from there) and then save the new token to the db.
There's no need to check cookies, those are used in the background but you should not have anything to do with them.
Edit
Don't use the cookies, they should not concern you at any time.
What you should do:
On the server side you should follow the instructions in the Server-Side auth guide, get the "code" and exchange it with a token.
That token will have 60 days.
Use that token, which you store in your db, as needed (other threads, what not) and when you are getting an error back from facebook saying that the token has expires just navigate the user back to the auth dialog page.
You can not use the "code" to get more than one token so that won't help you.
If the user session (and token) got invalidated (for various reasons) you will still get an error back from facebook when trying to make an api request, when that happens just send the user to the auth dialog again.
I am building a social gaming platform which will be played with mobiles. I am confused about the login part and access token. Let me briefly explain my problem.
Problem: User logs in with facebook login and I retrieve the accessToken of the user. Then immediately after login I store this accessToken in my database. The user continues with the game. Then in some point when I want to post something to the users wall the mobile side calls a WebService and my part (C#) uses the access token stored in the DB and posts something to the wall. Until here everything is OK. But what happens when the access Token expires or the user changes his password. Then I have to re-get the accessToken and update the DB.
BUT how do I get notified when the accessToken changes? I have to get notified or I will have a expired token and won't be able to post something.
Thanks
You won't get notified when a token expires, but Facebook give you the expiry time in your response, which you should store.
According to the OAuth spec, you will receive an HTTP 401 Unauthorized if you try to use an invalid/expired token, as well as the following:
Invalid Consumer Key
Invalid signature
Invalid / used nonce