I have a php websocket based application where the websocket is the core. Would it be a good idea to use sec-websocket-protocol for authentication.
This is my plan.
User logins using there credentials and I use php sessions to track the user between pages.
Now when user initiates the application a random token is generated and stored in Database which is then passed in the header when websocket is initiated. The header looks kind of
Cache-Control:no-cache
Connection:Upgrade
Host:tonywilk.no-ip.org:12352
Origin:http://********.com:port
Pragma:no-cache
Sec-WebSocket-Key:DMF3ByMTLq+cp7AyMN0qUA==
Sec-WebSocket-Protocol:**Token** **<-- browser sends token
Sec-WebSocket-Version:13
Upgrade:websocket
I use the token to verify the user and send server respons with handshake
Connection:Upgrade
Sec-WebSocket-Accept:L6wqtsHk6dzD+kd9NCYT6Wt7OCU=
Sec-WebSocket-Protocol: **Token** <-- server replies ok
Upgrade:WebSocket
Is this a good idea or is there a better way to do it
You should use Authorization header for authentication.
Using Sec-WebSocket-Protocol header for authentication is bad idea, because it changes the header meaning:
The |Sec-WebSocket-Protocol| header field is used in the WebSocket
opening handshake. It is sent from the client to the server and back
from the server to the client to confirm the subprotocol of the
connection. This enables scripts to both select a subprotocol and be
sure that the server agreed to serve that subprotocol. (c) RFC 6455 – The WebSocket Protocol
I'm using RatchetPHP for my websocket application.
I can't pass headers when opening a websocket connection, so I pass an OAuth2 token to the websocket uri. It looks like this:
new Websocket('ws://localhost:8482?access_token=XXX')
If you can easily retrieve query parameters in your websocket application, this is something you could try.
This is the trick I'm using in Sandstone: https://eole-io.github.io/sandstone/authentication.html
Related
I have already created an api using php slim framework. But I have an issue with securing my api. I want to access only api for the authenticated users only.
I have already added user login to my front end angular project. That is fine. But when the someone directly calls the api endpoint its show the result related to that endpoint.
For example. I have the following endpoint.
slimapi/customers/view
This endpoint shows all the data in the customer's table.
When someone types this URL in the browser. it shows all data related to that api endpoint. but I want to show some customers message when someone tries to access my api endpoint without using front end application.
You can Manage JWT Token
when client sends you login request and if login request and credential matched then you give the client a token. Then After every request, you check the token is it valid then you give the access.
just see the documentation of JWT
https://github.com/tuupola/slim-jwt-auth
You could use the OpenID Connect protocol (based on OAuth 2 and JSON Web Tokens).
But this would maybe an overkill for the most scenarios, because a JWT would only makes sense if you have to scale the "session" over multiple servers and/or load balancers in the back-end infrastructure. Also a simple logout is not possible with JWT based tokens. If you start to manage JWT blacklists on the server-side, the API will not be stateless anymore.
I think a very long API-Token within the HTTP header, e.g. a UUID, would be secure and good enough in the most cases.
The HTTP Authorization request header contains the credentials to authenticate a user agent with a server, usually after the server has responded with a 401 Unauthorized status and the WWW-Authenticate header.
Syntax:
Authorization: <type> <credentials>
Basic Auth
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Token based
Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ
UUID as Token
Authorization: Bearer bb79dfb5-17fd-4ebc-acd5-548e308e5f9a
Also make sure, that all API request are SSL (HTTPS) encrypted.
PS: If you just want secure your API for a web application, a classic Session with Cookies is also good enough and very secure.
I was building a server, and while trying to implement the websocket protocol, I ran into some problem.
As the question title describes, let's suppose I have defined two routes (/ws1, /ws2), which exposes multiple websocket connection.
And in case of a handshake I successfully can understand for which route the handshake request was sent.
The main problem in hand is that, when a subsequent websocket message is sent by the client, how is the server going to understand that which endpoint the websocket message was sent to.
After reading this: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers I understand that there is no such field in message which denotes the route.
Just in case: I am doing this in PHP.
The route never changes after the handshake is completed. The idea is that the WebSocket maintains a state-full connection, but that connection is first negotiated over HTTP. This is done by sending a normal HTTP request to a URI and the end-point is then responsible for maintaining the connection after it has been successfully negotiated.
As such it is your responsibility to keep track of the information in that initial HTTP request, after the WebSocket connection is negotiated, if you wish to make subsequent use of it.
If you look at how some current PHP implementations of WebSocket servers do it, for example Ratchet PHP, you'll see that the thing which handles the WebSocket requests receives a GuzzleHttp object, after the connection is successfully negotiated, in the onOpen callback handler. This contains all of the original HTTP request information tied to the client's connection object so you can continue to use that throughout.
So essentially a Connection object holds all of the information about the sateful TCP socket itself, coupled with the HTTP object, which could be implemented as something like a GuzzleHttp or PSR7 Message object. Each time a message is received from that Connection object, the coupled HTTP object can be access to lookup the related request line from the initial HTTP request.
A WebSocket connection is established using an HTTP GET request that upgrades the connection. You can identify clients based on the resource ID in PHP by casting the resource to an integer using (int) $resource.
TCP connections in general are identified by the source IP / source port / destination IP / destination port quadruple.
You have to keep the URI / endpoint info in an array or similar data structure and use the client ID as index. Then you can look up the endpoint upon receiving new messages.
I am currently learning about OAuth2, and I am slightly confused about one part of it. Does the OAuth2 server compare the domain in the JWT with the domain in the request header?
What prevents someone from ripping a bearer token out of a JS app and then using it to make fraudulent API requests? Even if HTTPS is used, the token sent back from OAuth2 still has to be stored before it can be used in subsequent requests, thus making it vulnerable. What am I missing?
Edit: what if I create an oauth2 token from a non-browser client and there is no domain name to match against?
Nothing prevents it from being used. That's why you store it safely or you don't store it at all.
So, I'm trying to use PHP Http sockets to execute a rest action on a distant server.
My goal is to have my PHP script automatically execute various actions that I usually perform when browsing "manually".
The distant website is an e-commerce oriented portal (no name provided) and connection is through HTTPS (I think that may be the problem here).
[There is no hacking here, just automation!]
I manage to execute several actions with my script like logging in to the website using my username and password, adding items to my cart etc.
Using Firebug I found that the action triggered for confirming order is /createOrder, but when I try to validate my order using my script with my session cookies I get a 401 Unauthorized error (detailed below)
So I tried several times to access this action with CURL using my usual username and password but I never manage to get access.
How is it possible that I could access it by browsing manually but not with my script? Is there a way to make it work?
Response headers include:
Server: Apache
X-Cnection: close
Content-Length: 1518
WWW-Authenticate: Basic realm="WebLogic Server"
X-Powered-By: Servlet/2.5 JSP/2.1t
"The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.46) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity MAY include relevant diagnostic information. HTTP access authentication is explained in section 11."
Problem solved.
It was a cookie issue.
I was not sending the token cookie correctly.
How Facebook chat is working? Can anyone give me idea? I mean they are using websocket or AJAX? How they have implemented it?
It's a comet (see wikipedia) model:
Comet is a web application model in which a long-held HTTP request
allows a web server to push data to a browser, without the browser
explicitly requesting it. Comet is an umbrella term, encompassing
multiple techniques for achieving this interaction. All these methods
rely on features included by default in browsers, such as JavaScript,
rather than on non-default plugins. The Comet approach differs from
the original model of the web, in which a browser requests a complete
web page at a time.
Example of comet framework is APE. It is for javascript, however comet can be written not only in javascript.
The user establishes a WebSocket connection through a process known as the WebSocket handshake. This process starts with the user sending a regular HTTP request to the server. An Upgrade header is included in this request that informs the server that the user wishes to establish a WebSocket connection.
WebSocket URLs use the ws scheme. There is also wss for secure WebSocket connections which is the equivalent of HTTPS.
If the server supports the WebSocket protocol, it agrees to the upgrade and communicates this through an Upgrade header in the response.
Now that the handshake is complete the initial HTTP connection is replaced by a WebSocket connection that uses the same underlying TCP/IP connection. At this point either party can starting sending data.
With WebSockets you can transfer as much data as you like without incurring the overhead associated with traditional HTTP requests. Data is transferred through a WebSocket as messages, each of which consists of one or more frames containing the data you are sending (the payload). In order to ensure the message can be properly reconstructed when it reaches the client each frame is prefixed with 4-12 bytes of data about the payload. Using this frame-based messaging system helps to reduce the amount of non-payload data that is transferred, leading to significant reductions in latency.