I need to create a REST api to authenticate a user the first time and retrieve other information based on this user for subsequent calls. If I'm not mistaken Restful services are stateless and therefore there is no need to store user information server side. My question is how can I guarantee user authentication for all the subsequent calls without a session?
This service is needed to create an android app that can display information on mobile.
You could use OAuth which is a widely used standard.
Another option is to use BASIC authentication over SSL. Any decent HTTP library would support BASIC auth. The client will be challenged the first time the request is made. Subsequent request need to send the BASIC auth headers over a secure line.
The there is the approach where you pass a secret to your client and use HMAC-SHA256 to send a hash of the URL params over to the server. Amazon does that and there is an article that covers how this is done. It is not as complicated as OAuth.
There are many approaches available but IMO your best best is to generate a AuthToken server side and return that to the client upon successful login. Then the client includes this on every request down to the server.
What I typical do is create a MD5 hash of a secret key and the the user's id- user's username - user's password - and the current date time. Then I store the token and the current date time in the db. on look ups after that I decode the token and compare the data points against the db values and if they match the user is good. This way is stateless and easily scalable.
Related
About the login step at Angular 6:
If I did it as the following:
Send username and password to PHP;
Server code check user if exists;
If really exists, we will send a json array again to Angular containing username and user role
Save them in localstorage
And when user try to navigate through the app, we will check these credentials using canActivate guard service.
Do we need to use JWT too to set a token or isn't necessary ?
Its not compulsory to use JWT, If your application requires extra
mission critical security use it.
Using JWT protects data from unwanted modifications before its received by the server. The unwanted modifications may be made by someone intercepting the data or from the user itself .
JWT just sends data to server in encoded format along with signature. So, that modification become little tough or even if made, data is not accepted by server as signature validation fails.
Sample JWT data passed :
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 // header
.eyJrZXkiOiJ2YWwiLCJpYXQiOjE0MjI2MDU0NDV9 // payload
.eUiabuiKv-8PYk2AkGY4Fb5KMZeorYBLw261JPQD5lM
Sample plain/json data
{
"username": "hello",
"full_name" : "Jason Bourne"
}
Here, you can easily see and modify the data passed, and in JWT you can't.
Yes! you need, because :
The token-based authentication systems allow users to enter their username and password in order to obtain a token which allows them to fetch a specific resource - without entering their username and password at each request. Once their token has been obtained, the user can use the token to access specific resources for a set time period.
JWT (pronounced 'jot') is a token based authentication system. It is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature. The JWT is a self-contained token which has authentication information, expire time information, and other user defined claims digitally signed.
Source: JWT (JSON Web Tokens) Are Better Than Session Cookies
more info: JWT
introduction: this link
Implementation example: php-authorization-jwt-json-web-tokens
It is not neccessary, but may come in handy.
If you have single application working on a single webserver you could skip JWT completely and just have a cookie autentication mechanism, so that each JavaScript call to the webserver contains your authentication cookie so your backend can respond with proper user data.
JWT comes in handy though when you have more servers involved. Think of SSO service acting as a glue between multiple related sites, like StackOverflow and others. You just pass the JWT token and each server can safely assume the data was not tampered with and have immediate access to the user's identity, some basic details etc.
I am new to PHP :). I am creating a REST API with PHP which would be used by mobile clients(Android and IOS). Currently the PHP website(yii) allows users to login with username and password(hashed and stored in DB). The way I think of implementing this is, I can have a login REST api call that authenticates the user and generates a token(some random number or sessionid) and sends a hash of that token to the client. The client then can pass that token on the http header everytime on the REST api call and the api methods will validate this on every call?
Now,
I want to know if there are any disadvantages of this approach?
Also are there any PHP examples of how to do this?
How does this token ensure security? Can someone sniff this token and send it in the request and the server will still allow it? Or Assuming i expire the token with time, should the mobile again authenticate to get a new token?
My answer isn't going to be the only one and I am sure you will get a lot of feedback on such a question.
First the hash. I wouldn't suggest doing it this way. The hash can be snitched in route by man in the middle attack etc. Generally sensitive information in the URL is a bad idea.
Why not use a common session? Authorize on the first call... then the session have been created on the server and the caller... this way you ensure that requests coming next is authorized.
The user/service/server can simply refer to the session cookie created and by doing so be validated. This way is much more secure and doesn't expose sensitive information.
And.. use HTTPS if possible of course... otherwise the information is also acceptable to attacks. It all depends on what level you want security. You can stack layers of security... but that might not make sense if your sending information about cats over the line :)
This is more of a procedure question question than a code fault one so please be kind if I have posted in the wrong place.
I have successfully authenticated a gplus user client-side so the browser is holding the google id ready for me to use. I now want to post some data to my website with that id as the user id but i want to protect it meaning I don't want just anyone with someone else's gplus id to be able to post to my web app (it has to be the authenticated user at that time).
Should I install the php serverside sdk and use that? If so how do i merge the client-side data with that?
Thanks
You're absolutely right about wanting to get the ID in a secure manner to make it hard to impersonate. There are two main options, both properties of the authResult object that comes back to the sign in callback:
Send the 'code' to the server. This is part of the OAuth 2.0 flow, and can be exchanged on the server side for an access token. From that you can make API calls as the user, and retrieve the user ID and other details. You can be confident who the user is, as only Google could have generated that code. This would involve using one of the client libraries to handle the token exchange.
Use the id_token. This is a base64 encoded blob of JSON which includes the user ID (and email address if you requested the 'email' scope). What makes it secure is that it includes a cryptographic signature, which the server can verify, so it cannot be created by someone other than Google. The id token can be used to get the user ID, and so can be used for looking up the user on the server, but doesn't give access to make API calls. The benefit is that it only requires up to date certificates for verification which don't change that often, so most calls require no further network traffic from the server to verify the user.
Which you use is up to you, but both will require some code on the server. In general, if you don't need to call any Google APIs from the server, or are concerned about maximum login performance then use the id_token. There's a bit more about that sort of architecture here: http://www.riskcompletefailure.com/2013/11/client-server-authentication-with-id.html
You can even combine the two. The first time a user signs in (when they see the consent screen) the code exchange will return not just an access token (for making calls), but also a long-lived refresh token, which you can store securely in a database. If you store that, you can use the id_token to look up the user quickly, but still use the refresh token to help with API access.
I'm writing a RESTful Webservice with the Slim Microframework and use GET for reading data from a mysql database (select query) and also POST/PUT/DELETE for insert/update/delete rows in the database.
My question is now, is this not a big security issue if everybody is able to write or delete data in the database? But how could I prevent this, I thought the ST in REST stands for state transfer (so the webservice is stateless), which is a contradiction to a state like being logged in or not. And if I would pass some login data with the client which is allowed to write in the database, couldn't a bad guy catch the logindata and fake requests with it and for example delete all entries?
So, whats the normal way to go with this, the only Slim Framework examples I had found always show the route examples, but not how to secure it.
Are there also some opportunities in the Slim Framework to implement this what I need? It should be as easy as possible and the request should be responded nearly as quick as without an authentification or similar. There are no sensitive data like passwords, for me it would be enough that not everybody with a cURL commandline tool can delete all rows or things like that.
Would be great if anybody could explain me what to do and/or give some examples. I also need to know, what I maybe will need to change at the clients which are allowed to send the requests.
Lots of thanks.
Each request has to be authenticated and authorised.
People often get tied up with the word 'stateless'. This really just means that from one request to the next, the RESTful service has no prior knowledge of the users state.
BUT, the service is obviously allowed to be aware of the authenticated user that has just made a request, else how would it decide if it should allow access?
Therefore, you can 'store' the authenticated user in some variable during each request. Then it's up to you how you use this information to authorize the request.
I like to keep it simple and have all my users as a resource in my URI chain. They make requests like users/{username}/someresource.
I authenticate using http basic authentication (over SSL) and authorise based on the URI. If the request failed authentication, its a 401 Unauthorized Request. If the URI {username} and authenticated {username} do not match, the request is a 403 forbidden. If it is authenticated and authorized, the request is allowed (http code dependant on http verb)
Now that's the web service covered, now on to the web service client. This of course HAS to store state, otherwise your user would have to log in every time they make a request.
You simply store the users session in the application (as per normal session management) with the addition that you store the username and password (encrypted of course) in the session. Now every time a request is made, your web service client needs to retrieve the username and password, and send it with the request to your web service.
It will be stateless, in the sense that there won't be a session or a cookie, really. You'd normally issue out a key that would be required for INSERT/UPDATE/DELETE.
It is then up to you to pass the key with each request and to determine when a key should expire.
It would be as safe as normal http authenticated sessions. These use a cookie etc to authenticate the connected user to the stored session state.
A stateless service would be no different - the token is passed to the service just as a token is stored in a cookie for normal http. If you are worried about sniffing (IE man in the middle attacks) you would secure the link via SSL.
The authentication token generated by the service would be encrypted and would include a salt which is also verified on the server for each request. You could also limit the session time to suit your paranoia, and also check changes in source IP, user agent etc and expire the user's token if these change.
I recently ran into similar problem. As recommended by people here, I have decided to go with OAuth Authentication.
I am using HybridAuth A php wrapper for OAuth and out of the box sign in solution for Facebook, Twitter, Google, LinkedIn, etc.
I've read about oAuth, Amazon REST API, HTTP Basic/Digest and so on but can't get it all into "single piece". This is probably the closest situation - Creating an API for mobile applications - Authentication and Authorization
I would like to built API-centric website - service. So (in the beginning) I would have an API in center and website (PHP + MySQL) would connect via cURL, Android and iPhone via their network interfaces. So 3 main clients - 3 API keys. And any other developer could also develop via API interface and they would get their own API key. API actions would be accepted/rejected based on userLevel status, if I'm an admin I can delete anything etc., all other can manipulate only their local (account) data.
First, authorization - should I use oAuth + xAuth or my some-kind-of-my-own implemenation (see http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)? As I understand, on Amazon service user is == API user (have API key). On my service I need to separate standard users/account (the one who registered on the website) and Developer Accounts (who should have their API key).
So I would firstly need to authorize the API key and then Authenticate the user itself. If I use Amazon's scheme to check developer's API keys (authorize their app), which sheme should I use for user authentication?
I read about getting a token via api.example.org/auth after (via HTTPS, HTTP Basic) posting my username and password and then forward it on every following request. How manage tokens if I'm logged in simultaneously on Android and a website? What about man-in-the-middle-attack if I'm using SSL only on first request (when username and password are transmitted) and just HTTP on every other? Isn't that a problem in this example Password protecting a REST service?
As allways, the best way to protect a key is not to transmit it.
That said, we typically use a scheme, where every "API key" has two parts: A non-secret ID (e.g. 1234) and a secret key (e.g. byte[64]).
If you give out an API key, store it (salted and hashed) in you
service's database.
If you give out user accounts (protected by password), store the
passwords (salted and hashed) in your service's database
Now when a consumer first accesses your API, to connect, have him
Send a "username" parameter ("john.doe" not secret)
Send a "APIkeyID" parameter ("1234", not secret)
and give him back
the salts from your database (In case one of the parameters is wrong,
just give back some repeatable salt - eg.
sha1(username+"notverysecret").
The timestamp of the server
The consumer should store the salt for session duration to keep things fast and smooth, and he should calculate and keep the time offset between client and server.
The consumer should now calculate the salted hashes of API key and password. This way the consumer has the exact same hashes for password and API key, as what is stored in your database, but without anything seceret ever going over the wire.
Now when a consumer subseqently accesses your API, to do real work, have him
Send a "username" parameter ("john.doe" not secret)
Send a "APIkeyID" parameter ("1234", not secret)
Send a "RequestSalt" parameter (byte[64], random, not secret)
Send a "RequestTimestamp" parameter (calculated from client time and known offset)
Send a "RequestToken" parameter (hash(passwordhash+request_salt+request_timestamp+apikeyhash))
The server should not accept timestamps more than say 2 seconds in the past, to make this safe against a replay attack.
The server can now calculate the same hash(passwordhash+request_salt+request_timestamp+apikeyhash) as the client, and be sure, that
the client knows the API key,
the client knows the correct password