I am using Opauth for users to login with their social networking accounts for a commenting system.
After reading around this particular site, it appears that the token is one way to identify the user by storing it in a session. However, I've also read that it isn't necessary to use the token, a User ID would suffice.
My question is, what determines whether you use a token or the User ID is simply enough to identify the user?
The uid uniquely identifies the user, but the token and secret are used to make requests to the Twitter/Facebook API's after you've gained access to the account.
If you aren't intending to make any additional requests the secret and token will not be of use to you.
I'll try to explain you the purpose of Access Tokens in reference to the Facebook API.
A uid (User Id) is something that can uniquely identify a user on Facebook. For example: 1786565687 (that's me by the way). Whereas, an Access Token is an opaque string that identifies a user, app, or page and can be used by the app to make graph API calls. A User Access Token for instance is needed any time the app calls an API to read, modify or write a specific person's Facebook data on their behalf.
I've also read that it isn't necessary to use the token, a User ID
would suffice.
This is true but using a user Id, you an only obtain a limited amount of information related to a particular user. For example: https://graph.facebook.com/1786565687 will provide you only a limited amount of information for the user Rahil Arora (that's me again) and you won't be able to write or modify on my behalf.
Whereas, using a valid Access Token, you an even write or modify a specific person's data on their behalf. Because of privacy checks, the majority of API end points on Facebook need to include an access token and therefore you can't access there end points by just using the user Id. You need a valid Access Token in order to access extra information related to a particular user. For example: https://graph.facebook.com/1786565687?access_token={Access_Token} will give you a lot more information than the previous call.
what determines whether you use a token or the User ID is simply
enough to identify the user?
Well, as you can see, you can choose either a token or just a user id depending on the type of action that you're willing to perform.
You can refer to the links posted in the answer for further information.
Related
I would really like some opinions on whether the following is a safe method as user authentication, and if not, please point out it's shortcomings.
React front end
PHP / MySQL based RESTful API on remote server
1) user signs up, data is posted to the API, user is emailed a single use activation link to ensure email is valid before they can access their account.
2) user signs in, API validates the data in all of the usual ways and then sends back a JSON object containing their user ID and an access token.
3) user ID and access token are set in localStorage on the users device upon receiving the data. React then grabs that data from localStorage and uses it to set and control the state in Redux stores providing an App wide Auth state.
4) user ID and access token are sent along with every future request made to the API. In the instances where a user isn't logged in, i.e - they don't supply a valid user id with matching token, they are automatically prevented from requesting anything that requires authentication at the very first entry point of the API. Suitable responses are sent back which in turn update the front end state to reflect a non-logged in user.
5) When the user logs out the access Token is deleted from localStorage.
A bit more detail about some the inner workings :
All tokens are generated server side and stored in the DB, they are random and unique bin2hex(random_bytes(32)) and only valid when supplied with the matching user ID. So changing the user ID in a request will result in a failed auth response, as will supplying a valid user ID with a mismatching or expired token.
Tokens are single use and a new token is generated, stored and then sent back in the response from every authenticated request along with the corresponding user ID. This may be overkill and put a lot of extra strain on the server. Would really like your opinions on this aspect especially please.
Tokens are set to expire in 2hrs regardless. So if the user leaves themselves logged in, they will be automatically logged out after 2hrs of inactivity.
User ID and Token are sent as part of the JSON body of every request (not in the headers). Is this a cause for concern?
At no point (other than sign up and login) is the users password transmitted or stored in localStorage or used by the React frontend. A matching user ID and Token is all that is required to validate the user after the initial authorization.
All connections are made via HTTPS.
Can you spot any glaring security risks in this approach? Am I missing the elephant in the room here?
Obviously the user ID and matching token is as good as supplying the users email and password on every request as far as auth goes, but I can't use PHP sessions or cookies* as the API is hosted on a different domain. This is the best workaround I could come up with without having to go down the JWT or Oauth route.
How flawed it could be in regards to how I am checking and validating data on the API can't be practically addressed here, but assuming that it is all being done correctly is this method secure enough in principle?
I look forward to and thank you in advance for your opinions :)
*without a ton of workarounds which would ultimately be superflous as this App can only be used with modern browsers which all support localStorage.
In my opinion is not save to store the token in the local store,
As said in https://auth0.com/docs/security/store-tokens
Since Browser local storage (or session storage) is not secure. Any data stored there may be vulnerable to cross-site scripting. If an attacker steals a token, they can gain access to and make requests to your API. Treat tokens like credit card numbers or passwords: don’t store them in local storage.
A better option is to use cookies since they are managed by the browser.
I am integrating Google's login Apis on a website, and I need to place the user's details in our databases to use it the next time they login.
Googles developer documents clearly out lines that developers should never store user IDs in a database, instead you should use Token IDs generated by google to auth the legitimacy of the user.
I completely agree with this, but a token's live cycle is only a short period of time. If we insert the token in our databases, the next time the user logs in, they token will be different to that in our database. So how do we auth users via token id with google sign in?
I've read all of googles developer docs https://developers.google.com/identity/sign-in/web/backend-auth and theres nothing specifically explaining this, other than their process of authentication.
Could someone please help who may have had experience in this ?
Thanks alot
This is googles warning
Warning: Do not accept plain user IDs, such as those you can get with
the GoogleSignInAccount.getId() method, on your backend server. A
modified client application can send arbitrary user IDs to your server
to impersonate users, so you must instead use verifiable ID tokens to
securely get the user IDs of signed-in users on the server side.
Googles developer documents clearly out lines that developers should never store user IDs in a database
No, they don’t.
They are telling you that your server should not trust user ids send to it directly by the client - because anyone could easily fake those.
Instead, you are supposed to send the token, that you acquired on the client side, to the server (those tokens can’t be “guessed”, therefor you can not simply fake them) - and then you make a server-side API call using that token, to get the user id.
I am looking to implement SSO in all my future php/angular applications. I see there are services (Auth0, oauth.io, etc) that are sort of the middle man of an SSO app and there are protocols such as OAuth 1.0/2.0 but in regards to creating a custom SSO solution (using aforementioned OAuth protocols, I assume), I am a little foggy on the complete flow of the process.
What I do get:
App gets Access Token
(optional) App validates Access Token
App (with Access Token) gets access to a particular API and returns result. For
example, Facebook profile information.
What I don't get:
What to do with that information once I have it. Do I retain the access token and request information from the API source each time they login? How do I relate my own application data to the API data? Would I create a different kind of user record that just contains the access token and application's userid?
Do I retain the access token and request information from the API source each time they login?
If the token does not expire, you can hold on to it in a data store and use it with each request. Many times, though, the token will expire, and you need to request a new one each time you start a session. In this case you'd probably store the token in memory instead of a permanent storage location.
How do I relate my own application data to the API data?
I think we'd need to know a little more about your application to answer this question.
Would I create a different kind of user record that just contains the access token and application's userid?
Again, we'd probably need a little more information about your application. If you were persisting the token (in the case that it doesn't expire), then you need to make some considerations about how you want to store it. If not, you can probably just put it into a local variable or session.
I'm working on a social hub page which aggregates info from all social networks. Currently I'm trying to fetch infos from one specific foursquare venue.
To get the information I want, I have to use an access token and therefore authenticate my user. In my case this would always be the same (my own) user.
Is there a way to get an access token with my username/password without having to redirect to the authentication page?
I couldn't find any answers here so far, thanks for your help!
Update:
I just discovered exactly what I want to implement on http://de.puma.com/creativefactory - if you scroll down you can see foursquare information on the bottom right corner, that's exactly what I want: Display how many users checked into my venue and the last persons who checked in. How did they do that, there is no auth dialog required? Thanks again!
Unfortunately, this is explicitly not allowed for security reasons. Although it may seem safe in your case, we don't generally want to support 3rd-party applications handling our users' passwords when OAuth makes it unnecessary. This is the same policy that many other large social networks have.
If you're just looking for venue information (e.g. just information about a venue and NOT any user information) then you don't need to have an authorized user. The venues API can be accessed with only your client ID and client secret. See the Foursquare API documentation..
Some of our endpoints that don’t pertain to specific user information,
such as venues search are enabled for userless access (meaning you
don’t need to have a user auth your app for access). To make a
userless request, specify your consumer key's Client ID and Secret
instead of an auth token in the request URL.
You should be able to get the required information without user authorisation.
Just create an app and you will be provided with a client id and client secret, you can then use these to access the API.
Here is the required venue API string format:
https://api.foursquare.com/v2/venues/[VENUE_ID]?client_id=[CLIENT_ID]&client_secret=[CLIENT_SECRET]&v=20120101
In the returned json you should find:
"hereNow":{"count":x,"summary":"x people here","groups":[]}
I am working on integrating Google Apps into my PHP app. I have already a login system that assigns a session ID to a user (after entering username and password), which gets stored in the database when the user is logged in. Session ID's become invalid after a certain time of inactivity (configurable by the user, can be 5 minutes, 15, 60...). That session ID is passed in the url to check if a user is still logged in. When logging out, the session ID is removed from the database.
I let people log in with Google by storing their Google ID in the database, when they log in, I request an access token, query the userinfo, see if the google ID is in the database and if so, assign a session ID to this user. Since I want to be able to query other API's I also store the access token json in the database. When a user logs out, the access token is also removed from the database.
This works, my users are able to log in using their Google account and I can query the API's using the stored access_token, however some things feel clunky of make me feel uncertain about my workflow:
If you force_approval you get a refresh_token, I feel like I should be using this refresh token to get a new access token, instead of removing the old one from the database and entering a new one when the user logs in again. On the other hand, when logging in, I do not know who it is yet, so I don't know which refresh token to use. Maybe I'm misunderstanding what the refresh token is for. Also, I don't really want to force approval every time, so I can't even use the refresh_token in that case.
As said before, users can determine how long their session will last, however, the google access_token always expires after 3600 seconds. It'd be really stupid if users would work an hour on the system and after that the Google API's suddenly fail, forcing them to log in again. The Google OAuth playground shows a checkbox "Auto-refresh token before it expires", but I'm not seeing how to do this. Do I have to use the refresh token here? Or simply request a new token in the background (if I'm not forcing approval)?
At the moment, I'm using the userinfo query (https://www.googleapis.com/oauth2/v2/userinfo) to find the user id, but I can also use the tokeninfo (https://www.googleapis.com/oauth2/v1/tokeninfo). Tokeninfo is not listed in the oauth playground, but the result does show how long the token remains valid (however, I can also calculate this myself). Is one preferable over the other?
I'm storing the entire json object in the database (access_token, id_token, expires_in and token_type) but I feel my app will still work perfectly if I only store the access_token (only problem I foresee is if the expires_in time changes). Do I need to store the id_token for example?
I find the Google documentation (at developers.google.com) sometimes very lacking, if anyone knows any other good sources of information, I'm interested in them as well.
I think it might help if you took a look at the lastest OpenID Connect Specs where concepts like the userinfo endpoint come from. OpenID connect is built on top of OAuth 2. There's quite a lot in there, but it's still probably worth a look. This blog article is also very good (as are others in the same blog).
Unfortunately, I don't think Google's implementation is currently up to date with the latest spec draft so it will probably be a moving target for some time. These things have changed a lot over the past year.
I agree with your first point that you should be obtaining a new access token each time you authenticate a user, rather than refreshing an old one. You don't know who the user is until they have logged in and granted you an access token. In general, the lifespan of an access token is not linked to the user's session. Once issued, your application could theoretically use it to access resources independently of the user's presence. If you want to carry on accessing the resource beyond the token expiry time, then you need to submit the refresh token at that point to obtain a new access token. I'm afraid I don't know what the "auto-refresh" feature is for.
I believe Google's tokeninfo is analogous to the check_id endpoint of OpenID connect, but accepts either an access token or an id token, rather than just the latter. Note that the expiry times of the two may differ. You would typically be able to retrieve more detailed user data from the userinfo endpoint than from check_id, which would normally return the bare user_id.
You shouldn't need to store the id_token. It is a bit like a record of the user's authentication by the authorization server. The access token is what your application will be interested in maintaining once you have validated the user identity.