feat: socketio using authorization headers
Earlier socketio only worked in browser where browser would send cookie (cause same domain) and hence socketio server used it to auth connection. This however is limited and doesn't allow simply creating socket connection from apps. Authorization headers on other hand are simple to implement.
This commit is contained in:
parent
17ebc5ee4d
commit
11ea7e4179
3 changed files with 27 additions and 15 deletions
|
|
@ -1,5 +1,4 @@
|
|||
const request = require("superagent");
|
||||
const { get_url } = require("../utils");
|
||||
const { frappe_request } = require("../utils");
|
||||
const log = console.log;
|
||||
|
||||
const WEBSITE_ROOM = "website";
|
||||
|
|
@ -114,11 +113,9 @@ function notify_disconnected_documents(socket) {
|
|||
function can_subscribe_doctype(args) {
|
||||
if (!args) return;
|
||||
if (!args.doctype) return;
|
||||
request
|
||||
.get(get_url(args.socket, "/api/method/frappe.realtime.can_subscribe_doctype"))
|
||||
frappe_request("/api/method/frappe.realtime.can_subscribe_doctype", args.socket)
|
||||
.type("form")
|
||||
.query({
|
||||
sid: args.socket.sid,
|
||||
doctype: args.doctype,
|
||||
})
|
||||
.end(function (err, res) {
|
||||
|
|
@ -166,11 +163,9 @@ function notify_subscribed_doc_users(args) {
|
|||
function can_subscribe_doc(args) {
|
||||
if (!args) return;
|
||||
if (!args.doctype || !args.docname) return;
|
||||
request
|
||||
.get(get_url(args.socket, "/api/method/frappe.realtime.can_subscribe_doc"))
|
||||
frappe_request("/api/method/frappe.realtime.can_subscribe_doc", args.socket)
|
||||
.type("form")
|
||||
.query({
|
||||
sid: args.socket.sid,
|
||||
doctype: args.doctype,
|
||||
docname: args.docname,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -24,22 +24,27 @@ function authenticate_with_frappe(socket, next) {
|
|||
}
|
||||
|
||||
let cookies = cookie.parse(socket.request.headers.cookie);
|
||||
let authorization_header = socket.request.headers.authorization;
|
||||
|
||||
if (!cookies.sid) {
|
||||
next(new Error("No sid transmitted."));
|
||||
if (!cookies.sid && !authorization_header) {
|
||||
next(new Error("No authentication method used. Use cookie or authorization header."));
|
||||
return;
|
||||
}
|
||||
|
||||
request
|
||||
.get(get_url(socket, "/api/method/frappe.realtime.get_user_info"))
|
||||
let auth_req = request.get(get_url(socket, "/api/method/frappe.realtime.get_user_info"));
|
||||
if (cookies.sid) {
|
||||
auth_req = auth_req.query({ sid: cookies.sid });
|
||||
} else {
|
||||
auth_req = auth_req.set("Authorization", authorization_header);
|
||||
}
|
||||
|
||||
auth_req
|
||||
.type("form")
|
||||
.query({
|
||||
sid: cookies.sid,
|
||||
})
|
||||
.then((res) => {
|
||||
socket.user = res.body.message.user;
|
||||
socket.user_type = res.body.message.user_type;
|
||||
socket.sid = cookies.sid;
|
||||
socket.authorization_header = authorization_header;
|
||||
next();
|
||||
})
|
||||
.catch((e) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const { get_conf } = require("../node_utils");
|
||||
const conf = get_conf();
|
||||
const request = require("superagent");
|
||||
|
||||
function get_url(socket, path) {
|
||||
if (!path) {
|
||||
|
|
@ -16,6 +17,17 @@ function get_url(socket, path) {
|
|||
return url + path;
|
||||
}
|
||||
|
||||
// Authenticates a partial request created using superagent
|
||||
function frappe_request(path, socket) {
|
||||
const partial_req = request.get(get_url(socket, path));
|
||||
if (socket.sid) {
|
||||
return partial_req.query({ sid: socket.sid });
|
||||
} else if (socket.authorization_header) {
|
||||
return partial_req.set("Authorization", socket.authorization_header);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get_url,
|
||||
frappe_request,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue